From a2c3aad8c1628423df8ae66df943026338bf2889 Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 18:14:23 +0100 Subject: [PATCH 001/726] [FIX] unmutable default in sale/sale.py bzr revid: ls@numerigraphe.fr-20120305171423-5opxnru256g4mm9c --- addons/sale/sale.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 82bfda7b580..9606b1fd004 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -326,7 +326,7 @@ class sale_order(osv.osv): self.log(cr, uid, id, message) return True - def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, order_lines, context={}): + def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, order_lines, context=None): if (not pricelist_id) or (not order_lines): return {} warning = { @@ -335,7 +335,7 @@ class sale_order(osv.osv): } return {'warning': warning} - def onchange_partner_order_id(self, cr, uid, ids, order_id, invoice_id=False, shipping_id=False, context={}): + def onchange_partner_order_id(self, cr, uid, ids, order_id, invoice_id=False, shipping_id=False, context=None): if not order_id: return {} val = {} @@ -501,7 +501,9 @@ class sale_order(osv.osv): 'res_id': inv_ids and inv_ids[0] or False, } - def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed', 'done', 'exception'], date_inv = False, context=None): + def action_invoice_create(self, cr, uid, ids, grouped=False, states=None, date_inv=False, context=None): + if states is None: + states = ['confirmed', 'done', 'exception'] res = False invoices = {} invoice_ids = [] From 5e4446f483acaf15aa85cbd339911d2711dae9f1 Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 18:32:36 +0100 Subject: [PATCH 002/726] [FIX] unmutable default in account/account.py bzr revid: ls@numerigraphe.fr-20120305173236-wdnj66ti4bopedzp --- addons/account/account.py | 52 +++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/addons/account/account.py b/addons/account/account.py index c1a30967aea..46b1374ccd0 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -591,12 +591,15 @@ class account_account(osv.osv): res.append((record['id'], name)) return res - def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False): + def copy(self, cr, uid, id, None, context=None, done_list=None, local=False): + if default is None: + default = {} + else: + default = default.copy() + if done_list is None: + done_list = [] account = self.browse(cr, uid, id, context=context) new_child_ids = [] - if not default: - default = {} - default = default.copy() default['code'] = (account['code'] or '') + '(copy)' if not local: done_list = [] @@ -765,11 +768,14 @@ class account_journal(osv.osv): (_check_currency, 'Configuration error! The currency chosen should be shared by the default accounts too.', ['currency','default_debit_account_id','default_credit_account_id']), ] - def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False): - journal = self.browse(cr, uid, id, context=context) - if not default: + def copy(self, cr, uid, id, default=None, context=None, done_list=None, local=False): + if default is None: default = {} - default = default.copy() + else: + default = default.copy() + if done_list is None: + done_list = [] + journal = self.browse(cr, uid, id, context=context) default['code'] = (journal['code'] or '') + '(copy)' default['name'] = (journal['name'] or '') + '(copy)' default['sequence_id'] = False @@ -1161,7 +1167,7 @@ class account_fiscalyear(osv.osv): 'end_journal_period_id':fields.many2one('account.journal.period','End of Year Entries Journal', readonly=True), } - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): default.update({ 'period_ids': [], 'end_journal_period_id': False @@ -1420,9 +1426,15 @@ class account_move(osv.osv): result = super(account_move, self).create(cr, uid, vals, context) return result - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): + if context is None: + default = {} + else: + default = default.copy() if context is None: context = {} + else: + context = context.copy() default.update({ 'state':'draft', 'name':'/', @@ -2239,7 +2251,9 @@ class account_model(osv.osv): _defaults = { 'legend': lambda self, cr, uid, context:_('You can specify year, month and date in the name of the model using the following labels:\n\n%(year)s: To Specify Year \n%(month)s: To Specify Month \n%(date)s: Current Date\n\ne.g. My model on %(date)s'), } - def generate(self, cr, uid, ids, datas={}, context=None): + def generate(self, cr, uid, ids, datas=None, context=None): + if datas is None: + datas = {} move_ids = [] entry = {} account_move_obj = self.pool.get('account.move') @@ -3193,7 +3207,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): property_obj.create(cr, uid, vals, context=context) return True - def _install_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, acc_ref={}, taxes_ref={}, tax_code_ref={}, context=None): + def _install_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, acc_ref=None, taxes_ref=None, tax_code_ref=None, context=None): ''' This function recursively loads the template objects and create the real objects from them. @@ -3211,6 +3225,12 @@ class wizard_multi_charts_accounts(osv.osv_memory): * a last identical containing the mapping of tax code templates and tax codes :rtype: tuple(dict, dict, dict) ''' + if acc_ref is None: + acc_ref = {} + if taxes_ref is None: + taxes_ref = {} + if tax_code_ref is None: + tax_code_ref = {} template = self.pool.get('account.chart.template').browse(cr, uid, template_id, context=context) if template.parent_id: tmp1, tmp2, tmp3 = self._install_template(cr, uid, template.parent_id.id, company_id, code_digits=code_digits, acc_ref=acc_ref, taxes_ref=taxes_ref, tax_code_ref=tax_code_ref, context=context) @@ -3223,7 +3243,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): tax_code_ref.update(tmp3) return acc_ref, taxes_ref, tax_code_ref - def _load_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, account_ref={}, taxes_ref={}, tax_code_ref={}, context=None): + def _load_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, account_ref=None, taxes_ref=None, tax_code_ref=None, context=None): ''' This function generates all the objects from the templates @@ -3241,6 +3261,12 @@ class wizard_multi_charts_accounts(osv.osv_memory): * a last identical containing the mapping of tax code templates and tax codes :rtype: tuple(dict, dict, dict) ''' + if account_ref is None: + account_ref = {} + if taxes_ref is None: + taxes_ref = {} + if tax_code_ref is None: + tax_code_ref = {} template = self.pool.get('account.chart.template').browse(cr, uid, template_id, context=context) obj_tax_code_template = self.pool.get('account.tax.code.template') obj_acc_tax = self.pool.get('account.tax') From f120f5aa5bd406b32839586d19555b1e629aec4d Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 18:41:11 +0100 Subject: [PATCH 003/726] [FIX] unmutable default in account bzr revid: ls@numerigraphe.fr-20120305174111-zf5j02cm7veyvzs4 --- addons/account/account_bank.py | 6 +++--- addons/account/account_move_line.py | 2 +- addons/account/project/wizard/account_analytic_chart.py | 2 +- .../wizard/account_analytic_inverted_balance_report.py | 2 +- .../project/wizard/project_account_analytic_line.py | 2 +- addons/account/report/account_balance.py | 2 +- addons/account/report/account_central_journal.py | 2 +- addons/account/report/account_general_journal.py | 2 +- addons/account/report/account_report.py | 2 +- addons/account/report/account_tax_report.py | 8 ++++++-- addons/account/res_currency.py | 2 +- addons/account/wizard/account_invoice_state.py | 2 +- addons/account/wizard/account_journal_select.py | 2 +- addons/account/wizard/account_move_bank_reconcile.py | 2 +- addons/account/wizard/account_move_journal.py | 2 +- .../account/wizard/account_move_line_reconcile_select.py | 2 +- addons/account/wizard/account_move_line_select.py | 2 +- .../wizard/account_move_line_unreconcile_select.py | 2 +- addons/account/wizard/account_period_close.py | 2 +- addons/account/wizard/account_reconcile.py | 2 +- .../account/wizard/account_reconcile_partner_process.py | 2 +- addons/account/wizard/account_state_open.py | 2 +- addons/account/wizard/account_subscription_generate.py | 2 +- addons/account/wizard/account_unreconcile.py | 2 +- 24 files changed, 31 insertions(+), 27 deletions(-) diff --git a/addons/account/account_bank.py b/addons/account/account_bank.py index 5a84dee53de..ebd9fd80f1a 100644 --- a/addons/account/account_bank.py +++ b/addons/account/account_bank.py @@ -29,12 +29,12 @@ class bank(osv.osv): 'currency_id': fields.related('journal_id', 'currency', type="many2one", relation='res.currency', readonly=True, string="Currency", help="Currency of the related account journal."), } - def create(self, cr, uid, data, context={}): + def create(self, cr, uid, data, context=None): result = super(bank, self).create(cr, uid, data, context=context) self.post_write(cr, uid, [result], context=context) return result - def write(self, cr, uid, ids, data, context={}): + def write(self, cr, uid, ids, data, context=None): result = super(bank, self).write(cr, uid, ids, data, context=context) self.post_write(cr, uid, ids, context=context) return result @@ -43,7 +43,7 @@ class bank(osv.osv): "Return the name to use when creating a bank journal" return (bank.bank_name or '') + ' ' + bank.acc_number - def post_write(self, cr, uid, ids, context={}): + def post_write(self, cr, uid, ids, context=None): if isinstance(ids, (int, long)): ids = [ids] diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 17120ee265e..50fbf08cc2d 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1097,7 +1097,7 @@ class account_move_line(osv.osv): 'has been confirmed!') % res[2]) return res - def _remove_move_reconcile(self, cr, uid, move_ids=[], context=None): + def _remove_move_reconcile(self, cr, uid, move_ids=None, context=None): # Function remove move rencocile ids related with moves obj_move_line = self.pool.get('account.move.line') obj_move_rec = self.pool.get('account.move.reconcile') diff --git a/addons/account/project/wizard/account_analytic_chart.py b/addons/account/project/wizard/account_analytic_chart.py index a10e938e293..92367e27da5 100644 --- a/addons/account/project/wizard/account_analytic_chart.py +++ b/addons/account/project/wizard/account_analytic_chart.py @@ -47,4 +47,4 @@ class account_analytic_chart(osv.osv_memory): return result account_analytic_chart() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/project/wizard/account_analytic_inverted_balance_report.py b/addons/account/project/wizard/account_analytic_inverted_balance_report.py index 2c9690fee50..95365716a22 100644 --- a/addons/account/project/wizard/account_analytic_inverted_balance_report.py +++ b/addons/account/project/wizard/account_analytic_inverted_balance_report.py @@ -52,4 +52,4 @@ class account_analytic_inverted_balance(osv.osv_memory): } account_analytic_inverted_balance() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/project/wizard/project_account_analytic_line.py b/addons/account/project/wizard/project_account_analytic_line.py index e49fbe911cb..54979d79b8a 100644 --- a/addons/account/project/wizard/project_account_analytic_line.py +++ b/addons/account/project/wizard/project_account_analytic_line.py @@ -55,4 +55,4 @@ class project_account_analytic_line(osv.osv_memory): project_account_analytic_line() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/report/account_balance.py b/addons/account/report/account_balance.py index c3117e60379..fdda9cb11ce 100644 --- a/addons/account/report/account_balance.py +++ b/addons/account/report/account_balance.py @@ -68,7 +68,7 @@ class account_balance(report_sxw.rml_parse, common_report_header): return self.pool.get('account.account').browse(self.cr, self.uid, data['form']['id']).company_id.name return super(account_balance ,self)._get_account(data) - def lines(self, form, ids=[], done=None):#, level=1): + def lines(self, form, ids=None, done=None): def _process_child(accounts, disp_acc, parent): account_rec = [acct for acct in accounts if acct['id']==parent][0] currency_obj = self.pool.get('res.currency') diff --git a/addons/account/report/account_central_journal.py b/addons/account/report/account_central_journal.py index d3113b63133..a42712f40d7 100644 --- a/addons/account/report/account_central_journal.py +++ b/addons/account/report/account_central_journal.py @@ -105,4 +105,4 @@ class journal_print(report_sxw.rml_parse, common_report_header): report_sxw.report_sxw('report.account.central.journal', 'account.journal.period', 'addons/account/report/account_central_journal.rml', parser=journal_print, header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/report/account_general_journal.py b/addons/account/report/account_general_journal.py index 9eb81157dba..0ffa08b31ef 100644 --- a/addons/account/report/account_general_journal.py +++ b/addons/account/report/account_general_journal.py @@ -158,4 +158,4 @@ class journal_print(report_sxw.rml_parse, common_report_header): report_sxw.report_sxw('report.account.general.journal', 'account.journal.period', 'addons/account/report/general_journal.rml', parser=journal_print, header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/report/account_report.py b/addons/account/report/account_report.py index 9f81f295d74..92d0fc95b85 100644 --- a/addons/account/report/account_report.py +++ b/addons/account/report/account_report.py @@ -283,4 +283,4 @@ class report_account_sales(osv.osv): )""") report_account_sales() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/report/account_tax_report.py b/addons/account/report/account_tax_report.py index 2a0c5987b47..cef1cf54af0 100644 --- a/addons/account/report/account_tax_report.py +++ b/addons/account/report/account_tax_report.py @@ -160,7 +160,7 @@ class tax_report(report_sxw.rml_parse, common_report_header): i+=1 return res - def _get_codes(self, based_on, company_id, parent=False, level=0, period_list=[], context=None): + def _get_codes(self, based_on, company_id, parent=False, level=0, period_list=None, context=None): obj_tc = self.pool.get('account.tax.code') ids = obj_tc.search(self.cr, self.uid, [('parent_id','=',parent),('company_id','=',company_id)], order='sequence', context=context) @@ -171,7 +171,11 @@ class tax_report(report_sxw.rml_parse, common_report_header): res += self._get_codes(based_on, company_id, code.id, level+1, context=context) return res - def _add_codes(self, based_on, account_list=[], period_list=[], context=None): + def _add_codes(self, based_on, account_list=None, period_list=None, context=None): + if account_list is None: + account_list = [] + if period_list is None: + period_list = [] res = [] obj_tc = self.pool.get('account.tax.code') for account in account_list: diff --git a/addons/account/res_currency.py b/addons/account/res_currency.py index 8c9c6a8b103..ce781a1e11a 100644 --- a/addons/account/res_currency.py +++ b/addons/account/res_currency.py @@ -44,4 +44,4 @@ class res_currency_account(osv.osv): res_currency_account() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_invoice_state.py b/addons/account/wizard/account_invoice_state.py index 7adcb908a34..4924f6762d5 100644 --- a/addons/account/wizard/account_invoice_state.py +++ b/addons/account/wizard/account_invoice_state.py @@ -71,4 +71,4 @@ class account_invoice_cancel(osv.osv_memory): account_invoice_cancel() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_journal_select.py b/addons/account/wizard/account_journal_select.py index 98099925e29..b91c195f6b3 100644 --- a/addons/account/wizard/account_journal_select.py +++ b/addons/account/wizard/account_journal_select.py @@ -47,4 +47,4 @@ class account_journal_select(osv.osv_memory): account_journal_select() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_move_bank_reconcile.py b/addons/account/wizard/account_move_bank_reconcile.py index 9be351ed440..65ff3f4501e 100644 --- a/addons/account/wizard/account_move_bank_reconcile.py +++ b/addons/account/wizard/account_move_bank_reconcile.py @@ -61,4 +61,4 @@ the bank account\nin the journal definition for reconciliation.')) account_move_bank_reconcile() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_move_journal.py b/addons/account/wizard/account_move_journal.py index 6756e0d06c6..4be80bd1bc3 100644 --- a/addons/account/wizard/account_move_journal.py +++ b/addons/account/wizard/account_move_journal.py @@ -38,7 +38,7 @@ class account_move_journal(osv.osv_memory): _defaults = { 'target_move': 'all' } - def _get_period(self, cr, uid, context={}): + def _get_period(self, cr, uid, context=None): """ Return default account period value """ diff --git a/addons/account/wizard/account_move_line_reconcile_select.py b/addons/account/wizard/account_move_line_reconcile_select.py index 8e57c57884d..e23212c514c 100644 --- a/addons/account/wizard/account_move_line_reconcile_select.py +++ b/addons/account/wizard/account_move_line_reconcile_select.py @@ -52,4 +52,4 @@ class account_move_line_reconcile_select(osv.osv_memory): account_move_line_reconcile_select() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_move_line_select.py b/addons/account/wizard/account_move_line_select.py index 4a2f40ec708..a99750a36fe 100644 --- a/addons/account/wizard/account_move_line_select.py +++ b/addons/account/wizard/account_move_line_select.py @@ -69,4 +69,4 @@ class account_move_line_select(osv.osv_memory): account_move_line_select() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_move_line_unreconcile_select.py b/addons/account/wizard/account_move_line_unreconcile_select.py index ad59493503d..26421eb4c0c 100644 --- a/addons/account/wizard/account_move_line_unreconcile_select.py +++ b/addons/account/wizard/account_move_line_unreconcile_select.py @@ -41,4 +41,4 @@ class account_move_line_unreconcile_select(osv.osv_memory): account_move_line_unreconcile_select() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_period_close.py b/addons/account/wizard/account_period_close.py index fecf43f07ab..6b070808bbd 100644 --- a/addons/account/wizard/account_period_close.py +++ b/addons/account/wizard/account_period_close.py @@ -60,4 +60,4 @@ class account_period_close(osv.osv_memory): account_period_close() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_reconcile.py b/addons/account/wizard/account_reconcile.py index 729792e2222..99a57f8f556 100644 --- a/addons/account/wizard/account_reconcile.py +++ b/addons/account/wizard/account_reconcile.py @@ -173,4 +173,4 @@ class account_move_line_reconcile_writeoff(osv.osv_memory): account_move_line_reconcile_writeoff() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_reconcile_partner_process.py b/addons/account/wizard/account_reconcile_partner_process.py index 7cfeff70891..fd34a222f1d 100644 --- a/addons/account/wizard/account_reconcile_partner_process.py +++ b/addons/account/wizard/account_reconcile_partner_process.py @@ -100,4 +100,4 @@ class account_partner_reconcile_process(osv.osv_memory): account_partner_reconcile_process() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_state_open.py b/addons/account/wizard/account_state_open.py index 62e837b7366..efa4baff3cc 100644 --- a/addons/account/wizard/account_state_open.py +++ b/addons/account/wizard/account_state_open.py @@ -41,4 +41,4 @@ class account_state_open(osv.osv_memory): account_state_open() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_subscription_generate.py b/addons/account/wizard/account_subscription_generate.py index 8efcd25b789..b14da9b4403 100644 --- a/addons/account/wizard/account_subscription_generate.py +++ b/addons/account/wizard/account_subscription_generate.py @@ -50,4 +50,4 @@ class account_subscription_generate(osv.osv_memory): account_subscription_generate() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_unreconcile.py b/addons/account/wizard/account_unreconcile.py index 0e6c38f9d7c..5494875cf26 100644 --- a/addons/account/wizard/account_unreconcile.py +++ b/addons/account/wizard/account_unreconcile.py @@ -50,4 +50,4 @@ class account_unreconcile_reconcile(osv.osv_memory): account_unreconcile_reconcile() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 559843258e2955edd0a7081eb5bc1f4c438a74fb Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 18:53:10 +0100 Subject: [PATCH 004/726] [FIX] unmutable default in stock bzr revid: ls@numerigraphe.fr-20120305175310-l3jcpsf3u0jtf2id --- addons/stock/report/product_stock.py | 4 +++- addons/stock/report/report_stock.py | 4 ++-- addons/stock/report/stock_by_location.py | 2 +- addons/stock/stock.py | 14 ++++++++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/addons/stock/report/product_stock.py b/addons/stock/report/product_stock.py index b7dd254234c..1d882ad632b 100644 --- a/addons/stock/report/product_stock.py +++ b/addons/stock/report/product_stock.py @@ -42,7 +42,9 @@ class external_pdf(render): class report_stock(report_int): - def create(self, cr, uid, ids, datas, context={}): + def create(self, cr, uid, ids, datas, context=None): + if context is None: + context = {} product_ids = ids if 'location_id' in context: location_id = context['location_id'] diff --git a/addons/stock/report/report_stock.py b/addons/stock/report/report_stock.py index 37e4f28c858..d11589ae462 100644 --- a/addons/stock/report/report_stock.py +++ b/addons/stock/report/report_stock.py @@ -74,7 +74,7 @@ class stock_report_prodlots(osv.osv): group by location_id, product_id, prodlot_id )""") - def unlink(self, cr, uid, ids, context={}): + def unlink(self, cr, uid, ids, context=None): raise osv.except_osv(_('Error !'), _('You cannot delete any record!')) @@ -131,7 +131,7 @@ class stock_report_tracklots(osv.osv): group by location_id, product_id, tracking_id )""") - def unlink(self, cr, uid, ids, context={}): + def unlink(self, cr, uid, ids, context=None): raise osv.except_osv(_('Error !'), _('You cannot delete any record!')) stock_report_tracklots() diff --git a/addons/stock/report/stock_by_location.py b/addons/stock/report/stock_by_location.py index 2dbe03a347e..8ed8800fb29 100644 --- a/addons/stock/report/stock_by_location.py +++ b/addons/stock/report/stock_by_location.py @@ -26,7 +26,7 @@ from report.interface import toxml #FIXME: we should use toxml class report_custom(report_rml): - def create_xml(self, cr, uid, ids, datas, context={}): + def create_xml(self, cr, uid, ids, datas, context=None): config = """ 09/09/2005 diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 885f7cd2077..9a0bc8ebfd2 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -345,22 +345,28 @@ class stock_location(osv.osv): }) return product_obj.get_product_available(cr, uid, product_ids, context=context) - def _product_get(self, cr, uid, id, product_ids=False, context=None, states=['done']): + def _product_get(self, cr, uid, id, product_ids=False, context=None, states=None): """ @param product_ids: @param states: @return: """ + if states is None: + states = ['done'] ids = id and [id] or [] return self._product_get_multi_location(cr, uid, ids, product_ids, context=context, states=states) - def _product_all_get(self, cr, uid, id, product_ids=False, context=None, states=['done']): + def _product_all_get(self, cr, uid, id, product_ids=False, context=None, states=None): + if states is None: + states = ['done'] # build the list of ids of children of the location given by id ids = id and [id] or [] location_ids = self.search(cr, uid, [('location_id', 'child_of', ids)]) return self._product_get_multi_location(cr, uid, location_ids, product_ids, context, states) - def _product_virtual_get(self, cr, uid, id, product_ids=False, context=None, states=['done']): + def _product_virtual_get(self, cr, uid, id, product_ids=False, context=None, states=None): + if states is None: + states = ['done'] return self._product_all_get(cr, uid, id, product_ids, context, ['confirmed', 'waiting', 'assigned', 'done']) def _product_reserve(self, cr, uid, ids, product_id, product_qty, context=None, lock=False): @@ -518,7 +524,7 @@ class stock_tracking(osv.osv): def unlink(self, cr, uid, ids, context=None): raise osv.except_osv(_('Error'), _('You can not remove a lot line !')) - def action_traceability(self, cr, uid, ids, context={}): + def action_traceability(self, cr, uid, ids, context=None): """ It traces the information of a product @param self: The object pointer. @param cr: A database cursor From 520e2c680f927f16cfb97f543e2f73f7ab9ae7ac Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 18:58:42 +0100 Subject: [PATCH 005/726] [FIX] unmutable default in account_analytic_plans bzr revid: ls@numerigraphe.fr-20120305175842-zpbl324ihaz7vj39 --- addons/account_analytic_plans/report/crossovered_analytic.py | 4 +++- .../wizard/analytic_plan_create_model.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/account_analytic_plans/report/crossovered_analytic.py b/addons/account_analytic_plans/report/crossovered_analytic.py index e2ad9e05b04..f1d8d67f445 100644 --- a/addons/account_analytic_plans/report/crossovered_analytic.py +++ b/addons/account_analytic_plans/report/crossovered_analytic.py @@ -113,7 +113,9 @@ class crossovered_analytic(report_sxw.rml_parse): result.append(res) return result - def _lines(self, form, ids={}): + def _lines(self, form, ids=None): + if ids is None: + ids = {} if not ids: ids = self.ids diff --git a/addons/account_analytic_plans/wizard/analytic_plan_create_model.py b/addons/account_analytic_plans/wizard/analytic_plan_create_model.py index 1cd3022f60b..ed5259f50bf 100644 --- a/addons/account_analytic_plans/wizard/analytic_plan_create_model.py +++ b/addons/account_analytic_plans/wizard/analytic_plan_create_model.py @@ -57,4 +57,4 @@ class analytic_plan_create_model(osv.osv_memory): analytic_plan_create_model() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 2d2a44dcf2e3b29e4fef4000792a064862967769 Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 5 Mar 2012 19:40:03 +0100 Subject: [PATCH 006/726] [FIX] unmutable default in the remaining modules [REF] coding style consistency lp bug: https://launchpad.net/bugs/525808 fixed bzr revid: ls@numerigraphe.fr-20120305184003-er00xtj9vtcw7gna --- .../report/crossovered_analytic.py | 6 +-- addons/account_anglo_saxon/__init__.py | 2 +- addons/account_anglo_saxon/sale.py | 43 ---------------- addons/account_asset/account_asset.py | 8 +-- .../report/analytic_account_budget_report.py | 8 +-- addons/account_budget/report/budget_report.py | 4 +- .../report/crossovered_budget_report.py | 4 +- .../wizard/account_budget_analytic.py | 2 +- .../account_budget_crossovered_report.py | 2 +- .../wizard/account_budget_report.py | 2 +- addons/account_coda/account_coda.py | 6 ++- addons/account_followup/__init__.py | 2 +- addons/account_followup/wizard/__init__.py | 2 +- .../wizard/account_followup_print.py | 2 +- .../wizard/account_invoice_special_message.py | 2 +- addons/account_payment/__init__.py | 2 +- addons/account_payment/account_invoice.py | 2 +- addons/account_payment/account_move_line.py | 4 +- addons/account_payment/account_payment.py | 4 +- addons/account_payment/report/__init__.py | 2 +- .../account_payment/report/payment_order.py | 4 +- addons/account_payment/wizard/__init__.py | 2 +- .../wizard/account_payment_order.py | 2 +- .../wizard/account_payment_pay.py | 2 +- .../account_payment_populate_statement.py | 2 +- addons/account_sequence/__init__.py | 2 +- addons/account_voucher/__init__.py | 2 +- addons/account_voucher/account_voucher.py | 6 ++- addons/account_voucher/report/__init__.py | 2 +- .../account_voucher/report/account_voucher.py | 2 +- .../report/account_voucher_print.py | 2 +- addons/account_voucher/wizard/__init__.py | 2 +- .../wizard/account_voucher_unreconcile.py | 2 +- addons/analytic/analytic.py | 2 +- addons/anonymization/anonymization.py | 4 +- addons/auction/auction.py | 2 +- addons/auction/barcode/code39.py | 2 +- addons/auction/barcode/common.py | 2 +- addons/auction/report/auction_invoice.py | 2 +- addons/auction/report/auction_total_rml.py | 8 +-- addons/auction/report/buyer_form_report.py | 2 +- addons/auction/report/buyer_list.py | 2 +- addons/auction/report/huissier.py | 2 +- addons/auction/report/photo_shadow.py | 2 +- addons/auction/report/seller_form_report.py | 2 +- addons/audittrail/audittrail.py | 10 ++-- addons/base_contact/base_contact.py | 6 +-- addons/base_crypt/crypt.py | 4 +- .../report/ir_module_reference_print_graph.py | 2 +- addons/base_module_quality/__init__.py | 2 +- .../base_module_quality.py | 18 +++++-- .../method_test/method_test.py | 2 +- .../object_test/object_test.py | 2 +- .../pep8_test/pep8_test.py | 2 +- .../structure_test/structure_test.py | 2 +- .../unit_test/unit_test.py | 2 +- .../wizard/module_quality_check.py | 2 +- .../wizard/quality_save_report.py | 2 +- .../workflow_test/workflow_test.py | 2 +- .../wizard/base_module_record_objects.py | 2 +- .../wizard/base_module_save.py | 2 +- .../openerp_sxw2rml/openerp_sxw2rml.py | 32 ++++++------ .../bin/script/About.py | 2 +- .../bin/script/AddAttachment.py | 16 +++--- .../bin/script/Change.py | 4 +- .../bin/script/ConvertBracesToField.py | 6 +-- .../bin/script/ConvertFieldsToBraces.py | 2 +- .../bin/script/ExportToRML.py | 2 +- .../bin/script/Expression.py | 6 +-- .../bin/script/Fields.py | 12 ++--- .../bin/script/ModifyExistingReport.py | 6 +-- .../bin/script/NewReport.py | 6 +-- .../bin/script/Repeatln.py | 8 +-- .../bin/script/SendToServer.py | 8 +-- .../bin/script/ServerParameter.py | 8 +-- .../bin/script/Translation.py | 12 ++--- .../bin/script/lib/error.py | 2 +- .../bin/script/lib/functions.py | 22 +++++--- .../bin/script/lib/logreport.py | 2 +- .../bin/script/lib/rpc.py | 4 +- .../bin/script/lib/tools.py | 6 +-- .../bin/script/modify.py | 2 +- .../test/test_fields.py | 6 ++- addons/base_setup/base_setup.py | 2 +- addons/base_synchro/base_synchro_obj.py | 8 +-- addons/base_vat/__init__.py | 2 +- addons/base_vat/res_company.py | 2 +- addons/caldav/caldav_node.py | 22 ++++---- addons/crm/crm.py | 4 +- addons/crm/crm_lead.py | 2 +- addons/crm_claim/crm_claim.py | 2 +- addons/crm_helpdesk/crm_helpdesk.py | 2 +- addons/crm_profiling/crm_profiling.py | 2 +- addons/delivery/wizard/delivery_sale_order.py | 2 +- addons/document/content_index.py | 8 +-- addons/document/document.py | 2 +- addons/document/document_directory.py | 6 +-- addons/document/nodes.py | 50 ++++++++++--------- addons/document/odt2txt.py | 6 +-- addons/document/std_index.py | 16 +++--- addons/document_webdav/document_webdav.py | 2 +- addons/document_webdav/redirect.py | 2 +- addons/document_webdav/test_davclient.py | 2 +- addons/document_webdav/webdav.py | 2 +- addons/document_webdav/webdav_server.py | 12 ++--- addons/email_template/html2text.py | 7 +-- .../wizard/mail_compose_message.py | 2 +- addons/event/event.py | 2 +- addons/event/report/__init__.py | 2 +- addons/event/res_partner.py | 2 +- addons/event/wizard/event_confirm.py | 2 +- addons/event_moodle/event_moodle.py | 2 +- addons/event_project/event_project.py | 2 +- .../wizard/event_project_retro.py | 2 +- addons/hr_attendance/wizard/__init__.py | 2 +- .../wizard/hr_attendance_bymonth.py | 2 +- .../wizard/hr_attendance_byweek.py | 2 +- .../wizard/hr_attendance_error.py | 2 +- addons/hr_evaluation/hr_evaluation.py | 2 +- .../report/report_contribution_register.py | 2 +- addons/hr_payroll/report/report_payslip.py | 2 +- .../report/report_payslip_details.py | 2 +- addons/hr_payroll_account/__init__.py | 2 +- addons/hr_payroll_account/wizard/__init__.py | 2 +- .../hr_payroll_payslips_by_employees.py | 2 +- addons/hr_recruitment/hr_recruitment.py | 2 +- .../hr_recruitment_create_partner_job.py | 4 +- .../wizard/hr_recruitment_employee_hired.py | 4 +- .../hr_timesheet_invoice.py | 2 +- .../report/account_analytic_profit.py | 2 +- .../wizard/hr_timesheet_invoice_create.py | 2 +- .../hr_timesheet_sheet/hr_timesheet_sheet.py | 4 +- .../wizard/hr_timesheet_current.py | 2 +- addons/idea/idea.py | 2 +- addons/import_base/import_framework.py | 2 +- addons/import_sugarcrm/import_sugarcrm.py | 6 +-- addons/l10n_be/__init__.py | 2 +- addons/l10n_be_invoice_bba/invoice.py | 12 ++--- addons/l10n_br/l10n_br.py | 2 +- addons/l10n_ch/partner.py | 2 +- addons/l10n_ch/payment.py | 2 +- addons/l10n_ch/report/report_webkit_html.py | 2 +- addons/l10n_ch/wizard/create_dta.py | 2 +- addons/l10n_fr/l10n_fr.py | 2 +- addons/l10n_fr/report/base_report.py | 2 +- addons/l10n_fr/wizard/fr_report_bilan.py | 2 +- .../wizard/fr_report_compute_resultant.py | 2 +- addons/l10n_lu/wizard/pdf_ext.py | 2 +- addons/lunch/report/order.py | 4 +- addons/mail/mail_thread.py | 2 +- .../mail/static/scripts/openerp_mailgate.py | 0 addons/membership/report/__init__.py | 2 +- addons/membership/report/report_membership.py | 2 +- addons/membership/wizard/__init__.py | 2 +- addons/mrp/mrp.py | 8 +-- addons/mrp/procurement.py | 2 +- addons/mrp/report/bom_structure.py | 4 +- addons/mrp/stock.py | 2 +- addons/mrp_operations/mrp_operations.py | 2 +- addons/plugin/plugin_handler.py | 2 +- .../point_of_sale/report/account_statement.py | 2 +- .../report/all_closed_cashbox_of_the_day.py | 18 +++---- addons/point_of_sale/report/pos_details.py | 6 +-- .../report/pos_details_summary.py | 4 +- addons/point_of_sale/report/pos_lines.py | 4 +- .../report/pos_payment_report.py | 6 +-- .../report/pos_payment_report_user.py | 4 +- addons/point_of_sale/report/pos_receipt.py | 2 +- addons/point_of_sale/report/pos_sales_user.py | 4 +- .../report/pos_sales_user_today.py | 4 +- .../point_of_sale/report/pos_users_product.py | 4 +- .../report/report_cash_register.py | 2 +- addons/procurement/company.py | 2 +- addons/product/product.py | 4 +- addons/product/report/product_pricelist.py | 8 +-- .../product_manufacturer.py | 2 +- addons/product_visible_discount/__init__.py | 2 +- addons/project/project.py | 24 +++++---- .../project/wizard/project_task_reevaluate.py | 2 +- addons/project_gtd/project_gtd.py | 2 +- .../project_gtd/wizard/project_gtd_empty.py | 2 +- addons/project_mailgate/project_mailgate.py | 4 +- addons/project_mrp/project_procurement.py | 2 +- addons/project_timesheet/project_timesheet.py | 2 +- .../project_timesheet/report/task_report.py | 4 +- addons/purchase/purchase.py | 4 +- .../purchase/wizard/purchase_order_group.py | 2 +- .../purchase_requisition.py | 2 +- addons/report_webkit/ir_report.py | 2 +- addons/report_webkit/report_helper.py | 2 +- addons/resource/faces/task.py | 3 +- addons/resource/resource.py | 2 +- addons/sale/edi/sale_order.py | 2 +- addons/sale/report/__init__.py | 2 +- addons/sale/wizard/__init__.py | 2 +- addons/sale/wizard/sale_make_invoice.py | 2 +- addons/sale_crm/__init__.py | 2 +- addons/sale_layout/sale_layout.py | 2 +- addons/sale_order_dates/sale_order_dates.py | 2 +- addons/stock/report/lot_overview.py | 2 +- addons/stock/report/lot_overview_all.py | 2 +- .../report/stock_inventory_move_report.py | 2 +- .../wizard/stock_invoice.py | 2 +- addons/stock_location/procurement_pull.py | 2 +- addons/stock_planning/stock_planning.py | 2 +- .../wizard/stock_planning_createlines.py | 2 +- addons/survey/survey.py | 4 +- addons/survey/wizard/__init__.py | 2 +- addons/survey/wizard/survey_answer.py | 10 ++-- addons/wiki/web/widgets/rss/feedparser.py | 4 +- .../wiki/web/widgets/wikimarkup/__init__.py | 6 ++- 211 files changed, 461 insertions(+), 440 deletions(-) delete mode 100644 addons/account_anglo_saxon/sale.py mode change 100755 => 100644 addons/document/odt2txt.py mode change 100755 => 100644 addons/document_webdav/test_davclient.py mode change 100755 => 100644 addons/email_template/html2text.py mode change 100755 => 100644 addons/mail/static/scripts/openerp_mailgate.py mode change 100755 => 100644 addons/wiki/web/widgets/rss/feedparser.py diff --git a/addons/account_analytic_plans/report/crossovered_analytic.py b/addons/account_analytic_plans/report/crossovered_analytic.py index f1d8d67f445..f990ade55a3 100644 --- a/addons/account_analytic_plans/report/crossovered_analytic.py +++ b/addons/account_analytic_plans/report/crossovered_analytic.py @@ -34,7 +34,7 @@ class crossovered_analytic(report_sxw.rml_parse): }) self.base_amount = 0.00 - def find_children(self,ref_ids): + def find_children(self, ref_ids): to_return_ids = [] final_list = [] parent_list = [] @@ -53,7 +53,7 @@ class crossovered_analytic(report_sxw.rml_parse): final_list.extend(set_list) return final_list #to_return_ids[0] - def set_account(self,cats): + def set_account(self, cats): lst = [] category = self.pool.get('account.analytic.account').read(self.cr, self.uid, cats) for cat in category: @@ -62,7 +62,7 @@ class crossovered_analytic(report_sxw.rml_parse): lst.extend(self.set_account(cat['child_ids'])) return lst - def _ref_lines(self,form): + def _ref_lines(self, form): result = [] res = {} acc_pool = self.pool.get('account.analytic.account') diff --git a/addons/account_anglo_saxon/__init__.py b/addons/account_anglo_saxon/__init__.py index 07b514d0327..440f8e87df7 100644 --- a/addons/account_anglo_saxon/__init__.py +++ b/addons/account_anglo_saxon/__init__.py @@ -23,4 +23,4 @@ import stock import purchase import invoice -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_anglo_saxon/sale.py b/addons/account_anglo_saxon/sale.py deleted file mode 100644 index e2cfa7bbb3b..00000000000 --- a/addons/account_anglo_saxon/sale.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from osv import fields, osv - -#class sale_order_line(osv.osv): -# _name = 'sale.order.line' -# _description = 'Sale Order line' -# _inherit = 'sale.order.line' -# -# def invoice_line_create(self, cr, uid, ids, context={}): -# line_ids = super('sale_order_line',self).invoice_line_create(cr, uid, ids, context) -# invoice_line_obj = self.pool.get('account.invoice.line') -# for line in invoice_line_obj.browse(cr, uid, line_ids): -# if line.product_id: -# a = line.product_id.product_tmpl_id.property_stock_account_output and line.product_id.product_tmpl_id.property_stock_account_output.id -# if not a: -# a = line.product_id.categ_id.property_stock_account_output_categ and line.product_id.categ_id.property_stock_account_output_categ.id -# if a: -# a = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, a) -# invoice_line_obj.write(cr, uid, line.id, {'account_id':a}) -# -#sale_order_line() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py index 97aec1d8487..48f41df1ef4 100644 --- a/addons/account_asset/account_asset.py +++ b/addons/account_asset/account_asset.py @@ -75,7 +75,7 @@ class account_asset_asset(osv.osv): _name = 'account.asset.asset' _description = 'Asset' - def _get_period(self, cr, uid, context={}): + def _get_period(self, cr, uid, context=None): periods = self.pool.get('account.period').find(cr, uid) if periods: return periods[0] @@ -176,7 +176,9 @@ class account_asset_asset(osv.osv): year = depreciation_date.year return True - def validate(self, cr, uid, ids, context={}): + def validate(self, cr, uid, ids, context=None): + if context is None: + context = {} return self.write(cr, uid, ids, { 'state':'open' }, context) @@ -304,7 +306,7 @@ class account_asset_asset(osv.osv): default.update({'depreciation_line_ids': [], 'state': 'draft'}) return super(account_asset_asset, self).copy(cr, uid, id, default, context=context) - def _compute_entries(self, cr, uid, ids, period_id, context={}): + def _compute_entries(self, cr, uid, ids, period_id, context=None): result = [] period_obj = self.pool.get('account.period') depreciation_obj = self.pool.get('account.asset.depreciation.line') diff --git a/addons/account_budget/report/analytic_account_budget_report.py b/addons/account_budget/report/analytic_account_budget_report.py index aa5d39f8d49..e29af98b6a3 100644 --- a/addons/account_budget/report/analytic_account_budget_report.py +++ b/addons/account_budget/report/analytic_account_budget_report.py @@ -35,7 +35,9 @@ class analytic_account_budget_report(report_sxw.rml_parse): }) self.context = context - def funct(self, object, form, ids={}, done=None, level=1): + def funct(self, object, form, ids=None, done=None, level=1): + if ids is None: + ids = {} if not ids: ids = self.ids if not done: @@ -153,7 +155,7 @@ class analytic_account_budget_report(report_sxw.rml_parse): tot['perc'] = float(tot['prac'] / tot['theo']) * 100 return result - def funct_total(self,form): + def funct_total(self, form): result = [] res = {} res = { @@ -167,4 +169,4 @@ class analytic_account_budget_report(report_sxw.rml_parse): report_sxw.report_sxw('report.account.analytic.account.budget', 'account.analytic.account', 'addons/account_budget/report/analytic_account_budget_report.rml',parser=analytic_account_budget_report,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_budget/report/budget_report.py b/addons/account_budget/report/budget_report.py index 7681f9268d9..c7d4ba58f68 100644 --- a/addons/account_budget/report/budget_report.py +++ b/addons/account_budget/report/budget_report.py @@ -34,7 +34,9 @@ class budget_report(report_sxw.rml_parse): }) self.context = context - def funct(self, object, form, ids={}, done=None, level=1): + def funct(self, object, form, ids=None, done=None, level=1): + if ids is None: + ids = {} if not ids: ids = self.ids if not done: diff --git a/addons/account_budget/report/crossovered_budget_report.py b/addons/account_budget/report/crossovered_budget_report.py index b70b7da34bb..9f2f59fe715 100644 --- a/addons/account_budget/report/crossovered_budget_report.py +++ b/addons/account_budget/report/crossovered_budget_report.py @@ -37,7 +37,9 @@ class budget_report(report_sxw.rml_parse): }) self.context = context - def funct(self, object, form, ids={}, done=None, level=1): + def funct(self, object, form, ids=None, done=None, level=1): + if ids is None: + ids = {} if not ids: ids = self.ids if not done: diff --git a/addons/account_budget/wizard/account_budget_analytic.py b/addons/account_budget/wizard/account_budget_analytic.py index 3e3b4b0fa9d..6397ee87c76 100644 --- a/addons/account_budget/wizard/account_budget_analytic.py +++ b/addons/account_budget/wizard/account_budget_analytic.py @@ -52,4 +52,4 @@ class account_budget_analytic(osv.osv_memory): account_budget_analytic() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_budget/wizard/account_budget_crossovered_report.py b/addons/account_budget/wizard/account_budget_crossovered_report.py index ff6b6492a5a..e120bc47caa 100644 --- a/addons/account_budget/wizard/account_budget_crossovered_report.py +++ b/addons/account_budget/wizard/account_budget_crossovered_report.py @@ -53,4 +53,4 @@ class account_budget_crossvered_report(osv.osv_memory): account_budget_crossvered_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_budget/wizard/account_budget_report.py b/addons/account_budget/wizard/account_budget_report.py index fdae4c94adf..6ef22c649e9 100644 --- a/addons/account_budget/wizard/account_budget_report.py +++ b/addons/account_budget/wizard/account_budget_report.py @@ -54,4 +54,4 @@ class account_budget_report(osv.osv_memory): account_budget_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_coda/account_coda.py b/addons/account_coda/account_coda.py index e3cc6f40a0c..48fc491bee9 100644 --- a/addons/account_coda/account_coda.py +++ b/addons/account_coda/account_coda.py @@ -217,7 +217,9 @@ class coda_bank_statement(osv.osv): _name = 'coda.bank.statement' _description = 'CODA Bank Statement' - def _default_journal_id(self, cr, uid, context={}): + def _default_journal_id(self, cr, uid, context=None): + if context is None: + context = {} if context.get('journal_id', False): return context['journal_id'] return False @@ -233,7 +235,7 @@ class coda_bank_statement(osv.osv): res[r] = round(res[r], 2) return res - def _get_period(self, cr, uid, context={}): + def _get_period(self, cr, uid, context=None): periods = self.pool.get('account.period').find(cr, uid) if periods: return periods[0] diff --git a/addons/account_followup/__init__.py b/addons/account_followup/__init__.py index 4bfe3186298..ffa88c40a32 100644 --- a/addons/account_followup/__init__.py +++ b/addons/account_followup/__init__.py @@ -23,4 +23,4 @@ import account_followup import wizard import report -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_followup/wizard/__init__.py b/addons/account_followup/wizard/__init__.py index aea714d2a86..ad072c5b7d8 100644 --- a/addons/account_followup/wizard/__init__.py +++ b/addons/account_followup/wizard/__init__.py @@ -21,4 +21,4 @@ import account_followup_print -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py index 1a5f3c0b60b..5ad3846dd71 100644 --- a/addons/account_followup/wizard/account_followup_print.py +++ b/addons/account_followup/wizard/account_followup_print.py @@ -209,7 +209,7 @@ class account_followup_print_all(osv.osv_memory): to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': stat_line_id} return {'partner_ids': partner_list, 'to_update': to_update} - def do_mail(self ,cr, uid, ids, context=None): + def do_mail(self, cr, uid, ids, context=None): mod_obj = self.pool.get('ir.model.data') move_obj = self.pool.get('account.move.line') user_obj = self.pool.get('res.users') diff --git a/addons/account_invoice_layout/wizard/account_invoice_special_message.py b/addons/account_invoice_layout/wizard/account_invoice_special_message.py index 27f6044a964..68edaf7cbe7 100644 --- a/addons/account_invoice_layout/wizard/account_invoice_special_message.py +++ b/addons/account_invoice_layout/wizard/account_invoice_special_message.py @@ -47,4 +47,4 @@ class account_invoice_special_msg(osv.osv_memory): account_invoice_special_msg() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/__init__.py b/addons/account_payment/__init__.py index 6188de6a9da..82a05aa73e9 100644 --- a/addons/account_payment/__init__.py +++ b/addons/account_payment/__init__.py @@ -29,4 +29,4 @@ import account_move_line import account_invoice import report -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/account_invoice.py b/addons/account_payment/account_invoice.py index fd787863c7d..7138540fa3b 100644 --- a/addons/account_payment/account_invoice.py +++ b/addons/account_payment/account_invoice.py @@ -50,4 +50,4 @@ class Invoice(osv.osv): Invoice() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/account_move_line.py b/addons/account_payment/account_move_line.py index 24f9486be95..d01157a8a98 100644 --- a/addons/account_payment/account_move_line.py +++ b/addons/account_payment/account_move_line.py @@ -26,7 +26,7 @@ from tools.translate import _ class account_move_line(osv.osv): _inherit = "account.move.line" - def amount_to_pay(self, cr, uid, ids, name, arg={}, context=None): + def amount_to_pay(self, cr, uid, ids, name, arg=None, context=None): """ Return the amount still to pay regarding all the payemnt orders (excepting cancelled orders)""" if not ids: @@ -117,4 +117,4 @@ class account_move_line(osv.osv): account_move_line() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/account_payment.py b/addons/account_payment/account_payment.py index 1de715dc777..c4257bf6f89 100644 --- a/addons/account_payment/account_payment.py +++ b/addons/account_payment/account_payment.py @@ -139,7 +139,9 @@ class payment_order(osv.osv): wf_service.trg_validate(uid, 'payment.order', ids[0], 'done', cr) return True - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} default.update({ 'state': 'draft', 'line_ids': [], diff --git a/addons/account_payment/report/__init__.py b/addons/account_payment/report/__init__.py index e9d7f4013ac..c73a5f33001 100644 --- a/addons/account_payment/report/__init__.py +++ b/addons/account_payment/report/__init__.py @@ -20,4 +20,4 @@ ############################################################################## import payment_order -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/report/payment_order.py b/addons/account_payment/report/payment_order.py index 0b2a8061906..6872bbe3516 100644 --- a/addons/account_payment/report/payment_order.py +++ b/addons/account_payment/report/payment_order.py @@ -77,7 +77,7 @@ class payment_order(report_sxw.rml_parse): user = pool.get('res.users').browse(self.cr, self.uid, self.uid) return user.company_id and user.company_id.currency_id and user.company_id.currency_id.symbol or False - def _get_account_name(self,bank_id): + def _get_account_name(self, bank_id): if bank_id: pool = pooler.get_pool(self.cr.dbname) value_name = pool.get('res.partner.bank').name_get(self.cr, self.uid, [bank_id]) @@ -87,4 +87,4 @@ class payment_order(report_sxw.rml_parse): report_sxw.report_sxw('report.payment.order', 'payment.order', 'addons/account_payment/report/payment_order.rml', parser=payment_order, header="external") -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/wizard/__init__.py b/addons/account_payment/wizard/__init__.py index 1c5aefacc78..35b907cd337 100644 --- a/addons/account_payment/wizard/__init__.py +++ b/addons/account_payment/wizard/__init__.py @@ -23,4 +23,4 @@ import account_payment_order import account_payment_populate_statement import account_payment_pay -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py index 613b049a412..fc421abe085 100644 --- a/addons/account_payment/wizard/account_payment_order.py +++ b/addons/account_payment/wizard/account_payment_order.py @@ -119,4 +119,4 @@ class payment_order_create(osv.osv_memory): payment_order_create() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/wizard/account_payment_pay.py b/addons/account_payment/wizard/account_payment_pay.py index 6bcb04fa490..3c16618f3d2 100644 --- a/addons/account_payment/wizard/account_payment_pay.py +++ b/addons/account_payment/wizard/account_payment_pay.py @@ -56,4 +56,4 @@ class account_payment_make_payment(osv.osv_memory): account_payment_make_payment() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/wizard/account_payment_populate_statement.py b/addons/account_payment/wizard/account_payment_populate_statement.py index 6f2d9d02dbc..ecfd4988329 100644 --- a/addons/account_payment/wizard/account_payment_populate_statement.py +++ b/addons/account_payment/wizard/account_payment_populate_statement.py @@ -120,4 +120,4 @@ class account_payment_populate_statement(osv.osv_memory): account_payment_populate_statement() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_sequence/__init__.py b/addons/account_sequence/__init__.py index b6707106d4b..e85a910f037 100644 --- a/addons/account_sequence/__init__.py +++ b/addons/account_sequence/__init__.py @@ -22,4 +22,4 @@ import account_sequence import account_sequence_installer -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/__init__.py b/addons/account_voucher/__init__.py index 9796f81d5e5..2b1478d9fa0 100644 --- a/addons/account_voucher/__init__.py +++ b/addons/account_voucher/__init__.py @@ -24,4 +24,4 @@ import invoice import report import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index 3ed173cca85..59a42ab3b24 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -830,7 +830,7 @@ class account_voucher(osv.osv): res['account_id'] = account_id return {'value':res} - def _sel_context(self, cr, uid, voucher_id,context=None): + def _sel_context(self, cr, uid, voucher_id, context=None): """ Select the context to use accordingly if it needs to be multicurrency or not. @@ -1251,7 +1251,9 @@ class account_voucher(osv.osv): move_line_pool.reconcile_partial(cr, uid, rec_ids, writeoff_acc_id=voucher.writeoff_acc_id.id, writeoff_period_id=voucher.period_id.id, writeoff_journal_id=voucher.journal_id.id) return True - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} default.update({ 'state': 'draft', 'number': False, diff --git a/addons/account_voucher/report/__init__.py b/addons/account_voucher/report/__init__.py index caeb155adbe..862843352a8 100644 --- a/addons/account_voucher/report/__init__.py +++ b/addons/account_voucher/report/__init__.py @@ -23,4 +23,4 @@ import account_voucher import account_voucher_print import account_voucher_sales_receipt -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/report/account_voucher.py b/addons/account_voucher/report/account_voucher.py index e44adee974e..146fcbc258a 100644 --- a/addons/account_voucher/report/account_voucher.py +++ b/addons/account_voucher/report/account_voucher.py @@ -72,4 +72,4 @@ report_sxw.report_sxw( parser=report_voucher,header="external" ) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/report/account_voucher_print.py b/addons/account_voucher/report/account_voucher_print.py index 8bd8644c03c..6a5762be493 100644 --- a/addons/account_voucher/report/account_voucher_print.py +++ b/addons/account_voucher/report/account_voucher_print.py @@ -93,4 +93,4 @@ report_sxw.report_sxw( parser=report_voucher_print,header="external" ) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/wizard/__init__.py b/addons/account_voucher/wizard/__init__.py index bfe32ba4b83..cc2f39f9d37 100644 --- a/addons/account_voucher/wizard/__init__.py +++ b/addons/account_voucher/wizard/__init__.py @@ -22,4 +22,4 @@ import account_voucher_unreconcile import account_statement_from_invoice -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_voucher/wizard/account_voucher_unreconcile.py b/addons/account_voucher/wizard/account_voucher_unreconcile.py index 42a9e1c5ec2..204839e3439 100644 --- a/addons/account_voucher/wizard/account_voucher_unreconcile.py +++ b/addons/account_voucher/wizard/account_voucher_unreconcile.py @@ -59,4 +59,4 @@ class account_voucher_unreconcile(osv.osv_memory): account_voucher_unreconcile() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py index 6241b6e06f0..6583de992b2 100644 --- a/addons/analytic/analytic.py +++ b/addons/analytic/analytic.py @@ -219,7 +219,7 @@ class account_analytic_account(osv.osv): default['line_ids'] = [] return super(account_analytic_account, self).copy(cr, uid, id, default, context=context) - def on_change_partner_id(self, cr, uid, id, partner_id, context={}): + def on_change_partner_id(self, cr, uid, id, partner_id, context=None): if not partner_id: return {'value': {'contact_id': False}} addr = self.pool.get('res.partner').address_get(cr, uid, [partner_id], ['invoice']) diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py index 39fb415e9e1..6e94838a4e7 100644 --- a/addons/anonymization/anonymization.py +++ b/addons/anonymization/anonymization.py @@ -350,7 +350,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): }) raise osv.except_osv(error_type, error_msg) - def anonymize_database(self,cr, uid, ids, context=None): + def anonymize_database(self, cr, uid, ids, context=None): """Sets the 'anonymized' state to defined fields""" # create a new history record: @@ -485,7 +485,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): 'target':'new', } - def reverse_anonymize_database(self,cr, uid, ids, context=None): + def reverse_anonymize_database(self, cr, uid, ids, context=None): """Set the 'clear' state to defined fields""" ir_model_fields_anonymization_model = self.pool.get('ir.model.fields.anonymization') diff --git a/addons/auction/auction.py b/addons/auction/auction.py index e701e399acf..03e6c805d78 100644 --- a/addons/auction/auction.py +++ b/addons/auction/auction.py @@ -533,7 +533,7 @@ class auction_lots(osv.osv): return self._sum_taxes_by_type_and_id(costs) # sum remise limite net and ristourne - def compute_seller_costs_summed(self, cr, uid, ids): #ach_pay_id + def compute_seller_costs_summed(self, cr, uid, ids): """This Fuction sum Net remittance limit and refund""" diff --git a/addons/auction/barcode/code39.py b/addons/auction/barcode/code39.py index a3926c6c48d..7dd7e5fca54 100644 --- a/addons/auction/barcode/code39.py +++ b/addons/auction/barcode/code39.py @@ -114,7 +114,7 @@ def _encode39(str, cksum): class _Code39Base(Barcode): - def __init__(self, value = "", **args): + def __init__(self, value="", **args): self.xdim = inch * 0.0075 self.lquiet = None self.rquiet = None diff --git a/addons/auction/barcode/common.py b/addons/auction/barcode/common.py index e6933fd1673..aa03b1079ca 100644 --- a/addons/auction/barcode/common.py +++ b/addons/auction/barcode/common.py @@ -39,7 +39,7 @@ class Barcode(Flowable): """Abstract Base for barcodes. Includes implementations of some methods suitable for the more primitive barcode types""" - def __init__(self, value = ''): + def __init__(self, value=''): self.value = value if not hasattr(self, 'gap'): diff --git a/addons/auction/report/auction_invoice.py b/addons/auction/report/auction_invoice.py index 40ca8498756..172c7dc73d3 100644 --- a/addons/auction/report/auction_invoice.py +++ b/addons/auction/report/auction_invoice.py @@ -26,7 +26,7 @@ class auction_invoice(report_int): def __init__(self, name): report_int.__init__(self, name) - def create(self,cr, uid, ids, datas, context): + def create(self, cr, uid, ids, datas, context): lots = self.pool.get('auction.lots').read(cr, uid, ids, ['ach_inv_id'], context=context) invoices = {} diff --git a/addons/auction/report/auction_total_rml.py b/addons/auction/report/auction_total_rml.py index 610cb108cc4..38f9adaa040 100644 --- a/addons/auction/report/auction_total_rml.py +++ b/addons/auction/report/auction_total_rml.py @@ -65,7 +65,7 @@ class auction_total_rml(report_sxw.rml_parse): return auct_dat - def sum_taxes(self,auction_id): + def sum_taxes(self, auction_id): self.cr.execute("select count(1) from auction_lots where id IN %s and auction_id=%s group by auction_id ", (tuple(self.total_obj),auction_id,)) res = self.cr.fetchone() return res[0] @@ -105,17 +105,17 @@ class auction_total_rml(report_sxw.rml_parse): res = self.cr.fetchone() return str(res[0]) or 0.0 - def sum_credit(self,auction_id): + def sum_credit(self, auction_id): self.cr.execute("select sum(buyer_price) from auction_lots where id IN %s and auction_id=%s", (tuple(self.total_obj),auction_id,)) res = self.cr.fetchone() return str(res[0]) - def sum_debit_buyer(self,auction_id): + def sum_debit_buyer(self, auction_id): self.cr.execute("select sum(buyer_price) from auction_lots where id IN %s and auction_id=%s", (tuple(self.total_obj),auction_id,)) res = self.cr.fetchone() return str(res[0] or 0) - def sum_debit(self,object_id): + def sum_debit(self, object_id): self.cr.execute("select sum(seller_price) from auction_lots where auction_id=%s", (object_id,)) res = self.cr.fetchone() return str(res[0] or 0) diff --git a/addons/auction/report/buyer_form_report.py b/addons/auction/report/buyer_form_report.py index 37b82cd872e..dea4c836f2b 100644 --- a/addons/auction/report/buyer_form_report.py +++ b/addons/auction/report/buyer_form_report.py @@ -58,7 +58,7 @@ class buyer_form_report(report_sxw.rml_parse): lots.append(object) return ret_dict.values() - def grand_buyer_total(self,o): + def grand_buyer_total(self, o): grand_total = 0 for oo in o: grand_total =grand_total + oo['obj_price'] +self.sum_taxes(oo) diff --git a/addons/auction/report/buyer_list.py b/addons/auction/report/buyer_list.py index 3829238a43f..1b088e40330 100644 --- a/addons/auction/report/buyer_list.py +++ b/addons/auction/report/buyer_list.py @@ -62,7 +62,7 @@ class buyer_list(report_sxw.rml_parse): auct_dat.append(auc_dates_fields) return auct_dat - def lines_lots_auct_lot(self,obj): + def lines_lots_auct_lot(self, obj): auc_date_ids = self.pool.get('auction.dates').search(self.cr, self.uid, ([('name','like',obj['name'])])) diff --git a/addons/auction/report/huissier.py b/addons/auction/report/huissier.py index 1d680548886..e9d7cc145da 100644 --- a/addons/auction/report/huissier.py +++ b/addons/auction/report/huissier.py @@ -30,7 +30,7 @@ class report_custom(report_rml): def __init__(self, name, table, tmpl, xsl): report_rml.__init__(self, name, table, tmpl, xsl) - def create_xml(self,cr, uid, ids, datas, context=None): + def create_xml(self, cr, uid, ids, datas, context=None): pool= pooler.get_pool(cr.dbname) lots = pool.get('auction.lots').browse(cr, uid, ids, context=context) auction = lots[0].auction_id diff --git a/addons/auction/report/photo_shadow.py b/addons/auction/report/photo_shadow.py index 919fa701e23..fb9cfe4f893 100644 --- a/addons/auction/report/photo_shadow.py +++ b/addons/auction/report/photo_shadow.py @@ -19,7 +19,7 @@ # ############################################################################## -def convert_catalog(from_file, to_file, size=220) : +def convert_catalog(from_file, to_file, size=220): return __convert(from_file, to_file, size) def convert(from_file, to_file): diff --git a/addons/auction/report/seller_form_report.py b/addons/auction/report/seller_form_report.py index 06ff021dcc1..c602cce0714 100644 --- a/addons/auction/report/seller_form_report.py +++ b/addons/auction/report/seller_form_report.py @@ -58,7 +58,7 @@ class seller_form_report(report_sxw.rml_parse): lots = partner.get('lots') lots.append(object) return ret_dict.values() - def grand_seller_total(self,o): + def grand_seller_total(self, o): grand_total = 0 for oo in o: grand_total =grand_total + oo['obj_price']+ self.sum_taxes(oo) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 302d6e146bd..25ba8e1c8b6 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -201,7 +201,7 @@ class audittrail_objects_proxy(object_proxy): res = value return res - def create_log_line(self, cr, uid, log_id, model, lines=[]): + def create_log_line(self, cr, uid, log_id, model, lines=None): """ Creates lines for changed fields with its old and new values @@ -210,6 +210,8 @@ class audittrail_objects_proxy(object_proxy): @param model: Object which values are being changed @param lines: List of values for line is to be created """ + if lines is None: + lines = [] pool = pooler.get_pool(cr.dbname) obj_pool = pool.get(model.model) model_pool = pool.get('ir.model') @@ -348,7 +350,7 @@ class audittrail_objects_proxy(object_proxy): data[(model.id, resource_id)] = {'text':values_text, 'value': values} return data - def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=[]): + def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None): """ This function compares the old data (i.e before the method was executed) and the new data (after the method was executed) and returns a structure with all the needed information to @@ -378,6 +380,8 @@ class audittrail_objects_proxy(object_proxy): record (res.partner, for example), we may have to log a change done in a x2many field (on res.partner.address, for example) """ + if field_list is None: + field_list = [] key = (model.id, resource_id) lines = { key: [] @@ -416,7 +420,7 @@ class audittrail_objects_proxy(object_proxy): lines[key].append(data) return lines - def process_data(self, cr, uid, pool, res_ids, model, method, old_values={}, new_values={}, field_list=[]): + def process_data(self, cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None): """ This function processes and iterates recursively to log the difference between the old data (i.e before the method was executed) and the new data and creates audittrail log diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py index 59ac8a0b4df..0106ce6ae2c 100644 --- a/addons/base_contact/base_contact.py +++ b/addons/base_contact/base_contact.py @@ -175,7 +175,7 @@ class res_partner_address(osv.osv): ids = self.pool.get('res.partner.location').search(cr, uid, [('partner_id','=',context['default_partner_id'])], context=context) return ids and ids[0] or False - def onchange_location_id(self,cr, uid, ids, location_id=False, context={}): + def onchange_location_id(self, cr, uid, ids, location_id=False, context=None): if not location_id: return {} location = self.pool.get('res.partner.location').browse(cr, uid, location_id, context=context) @@ -209,7 +209,7 @@ class res_partner_address(osv.osv): 'name' : fields.related('contact_id', 'name', type='char', size=64, string="Contact Name", store=True), 'title' : fields.related('contact_id', 'title', type='many2one', relation='res.partner.title', string="Title", store=True), } - def create(self, cr, uid, data, context={}): + def create(self, cr, uid, data, context=None): if not data.get('location_id', False): loc_id = self.pool.get('res.partner.location').create(cr, uid, { 'street': data.get('street',''), @@ -241,7 +241,7 @@ class res_partner_address(osv.osv): 'location_id': _default_location_id } - def default_get(self, cr, uid, fields=[], context=None): + def default_get(self, cr, uid, fields=None, context=None): if context is None: context = {} if 'default_type' in context: diff --git a/addons/base_crypt/crypt.py b/addons/base_crypt/crypt.py index c2fd0a25ef8..82cd939a015 100644 --- a/addons/base_crypt/crypt.py +++ b/addons/base_crypt/crypt.py @@ -45,7 +45,9 @@ from service import security magic_md5 = '$1$' -def gen_salt( length=8, symbols=ascii_letters + digits ): +def gen_salt( length=8, symbols=None): + if symbols is None: + symbols = ascii_letters + digits seed() return ''.join( sample( symbols, length ) ) diff --git a/addons/base_module_doc_rst/report/ir_module_reference_print_graph.py b/addons/base_module_doc_rst/report/ir_module_reference_print_graph.py index 62848383000..e70b2da63b1 100644 --- a/addons/base_module_doc_rst/report/ir_module_reference_print_graph.py +++ b/addons/base_module_doc_rst/report/ir_module_reference_print_graph.py @@ -79,4 +79,4 @@ report_sxw.report_sxw('report.ir.module.reference.graph', 'ir.module.module', 'addons/base_module_doc_rst/report/ir_module_reference_graph.rml', parser=ir_module_reference_print_graph, header=False) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/__init__.py b/addons/base_module_quality/__init__.py index 8ff78f7c202..602710fb602 100644 --- a/addons/base_module_quality/__init__.py +++ b/addons/base_module_quality/__init__.py @@ -22,4 +22,4 @@ import base_module_quality import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/base_module_quality.py b/addons/base_module_quality/base_module_quality.py index bbe20bc0b4f..349821f1081 100644 --- a/addons/base_module_quality/base_module_quality.py +++ b/addons/base_module_quality/base_module_quality.py @@ -115,7 +115,9 @@ class abstract_quality_check(object): self.log.debug('get_objects() obj_list: %s', ','.join(obj_list)) return obj_list - def get_model_ids(self, cr, uid, models=[]): + def get_model_ids(self, cr, uid, models=None): + if models is None: + models = [] # This function returns all ids of the given objects.. if not models: return [] @@ -133,7 +135,12 @@ class abstract_quality_check(object): result_ids[obj] = ids return result_ids - def format_table(self, header=[], data_list={}): #This function can work forwidget="text_wiki" + def format_table(self, header=None, data_list=None): + #This function can work forwidget="text_wiki" + if header is None: + header = [] + if data_list is None: + data_list = {} detail = "" detail += (header[0]) % tuple(header[1]) frow = '\n|-' @@ -144,7 +151,12 @@ class abstract_quality_check(object): detail = detail + '\n|}' return detail - def format_html_table(self, header=[], data_list=[]): #This function can work for widget="html_tag" + def format_html_table(self, header=None, data_list=None): + #This function can work for widget="html_tag" + if header is None: + header = [] + if data_list is None: + data_list = [] # function create html table.... detail = "" detail += (header[0]) % tuple(header[1]) diff --git a/addons/base_module_quality/method_test/method_test.py b/addons/base_module_quality/method_test/method_test.py index 2884e064b54..a708c088b80 100644 --- a/addons/base_module_quality/method_test/method_test.py +++ b/addons/base_module_quality/method_test/method_test.py @@ -85,4 +85,4 @@ This test checks if the module classes are raising exception when calling basic detail += self.format_table(header, dict_method) return detail -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/object_test/object_test.py b/addons/base_module_quality/object_test/object_test.py index 0a3f8ce379d..810b0a215a8 100644 --- a/addons/base_module_quality/object_test/object_test.py +++ b/addons/base_module_quality/object_test/object_test.py @@ -208,4 +208,4 @@ Test checks for fields, views, security rules, dependancy level return res return "" -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/pep8_test/pep8_test.py b/addons/base_module_quality/pep8_test/pep8_test.py index 4aaaaa7bddc..ef347cdaad4 100644 --- a/addons/base_module_quality/pep8_test/pep8_test.py +++ b/addons/base_module_quality/pep8_test/pep8_test.py @@ -278,4 +278,4 @@ PEP-8 Test , copyright of py files check, method can not call from loops return res return "" -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/structure_test/structure_test.py b/addons/base_module_quality/structure_test/structure_test.py index 2238d5f3a93..f8fef4d46f4 100644 --- a/addons/base_module_quality/structure_test/structure_test.py +++ b/addons/base_module_quality/structure_test/structure_test.py @@ -176,4 +176,4 @@ This test checks if the module satisfy tiny structure return res return "" -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/unit_test/unit_test.py b/addons/base_module_quality/unit_test/unit_test.py index 248f647310c..be378ced45f 100644 --- a/addons/base_module_quality/unit_test/unit_test.py +++ b/addons/base_module_quality/unit_test/unit_test.py @@ -111,4 +111,4 @@ This test checks the Unit Test(PyUnit) Cases of the module. Note that 'unit_test return detail + html +'' return '' -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/wizard/module_quality_check.py b/addons/base_module_quality/wizard/module_quality_check.py index 8b6f1157a29..6d03843e8b5 100644 --- a/addons/base_module_quality/wizard/module_quality_check.py +++ b/addons/base_module_quality/wizard/module_quality_check.py @@ -49,4 +49,4 @@ class quality_check(osv.osv_memory): quality_check() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/wizard/quality_save_report.py b/addons/base_module_quality/wizard/quality_save_report.py index e4286e92237..d9e7c08b424 100644 --- a/addons/base_module_quality/wizard/quality_save_report.py +++ b/addons/base_module_quality/wizard/quality_save_report.py @@ -49,4 +49,4 @@ class quality_save_report(osv.osv_memory): quality_save_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/workflow_test/workflow_test.py b/addons/base_module_quality/workflow_test/workflow_test.py index 11f7bcf12c3..5b27689eb2f 100644 --- a/addons/base_module_quality/workflow_test/workflow_test.py +++ b/addons/base_module_quality/workflow_test/workflow_test.py @@ -155,4 +155,4 @@ class quality_test(base_module_quality.abstract_quality_check): count = self.count_button(node, count) return count -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_record/wizard/base_module_record_objects.py b/addons/base_module_record/wizard/base_module_record_objects.py index e822c68c8fe..868a377a106 100644 --- a/addons/base_module_record/wizard/base_module_record_objects.py +++ b/addons/base_module_record/wizard/base_module_record_objects.py @@ -127,7 +127,7 @@ class base_module_record_objects(osv.osv_memory): _name = 'base.module.record.objects' _description = "Base Module Record Objects" - def inter_call(self,cr,uid,data,context=None): + def inter_call(self, cr, uid, data, context=None): res=base_module_save._create_module(self, cr, uid, data, context) mod_obj = self.pool.get('ir.model.data') model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_create_form_view')], context=context) diff --git a/addons/base_module_record/wizard/base_module_save.py b/addons/base_module_record/wizard/base_module_save.py index 1d54e212a28..914e5cbddac 100644 --- a/addons/base_module_record/wizard/base_module_save.py +++ b/addons/base_module_record/wizard/base_module_save.py @@ -167,4 +167,4 @@ class base_module_save(osv.osv_memory): base_module_save() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py b/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py index 4819007f1d0..32c05a2c768 100644 --- a/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py +++ b/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py @@ -42,11 +42,11 @@ import copy class DomApiGeneral: """General DOM API utilities.""" - def __init__(self,content_string="",file=""): + def __init__(self, content_string="", file=""): self.content_string = content_string self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)") - def _unitTuple(self,string): + def _unitTuple(self, string): """Split values and units to a tuple.""" temp = self.re_digits.findall(string) if not temp: @@ -54,13 +54,15 @@ class DomApiGeneral: else: return (temp[0]) - def stringPercentToFloat(self,string): + def stringPercentToFloat(self, string): temp = string.replace("""%""","") return float(temp)/100 - def findChildrenByName(self,parent,name,attr_dict={}): + def findChildrenByName(self, parent, name, attr_dict=None): """Helper functions. Does not work recursively. Optional: also test for certain attribute/value pairs.""" + if attr_dict is None: + attr_dict = {} children = [] for c in parent.childNodes: if c.nodeType == c.ELEMENT_NODE and c.nodeName == name: @@ -70,7 +72,7 @@ class DomApiGeneral: else: return self._selectForAttributes(nodelist=children,attr_dict=attr_dict) - def _selectForAttributes(self,nodelist,attr_dict): + def _selectForAttributes(self, nodelist, attr_dict): "Helper function.""" selected_nodes = [] for n in nodelist: @@ -83,7 +85,7 @@ class DomApiGeneral: selected_nodes.append(n) return selected_nodes - def _stringToTuple(self,s): + def _stringToTuple(self, s): """Helper function.""" try: temp = string.split(s,",") @@ -91,13 +93,13 @@ class DomApiGeneral: except: return None - def _tupleToString(self,t): + def _tupleToString(self, t): try: return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1])) except: return None - def _lengthToFloat(self,value): + def _lengthToFloat(self, value): v = value if not self.re_digits.search(v): return v @@ -113,7 +115,7 @@ class DomApiGeneral: except: return v - def openOfficeStringUtf8(self,string): + def openOfficeStringUtf8(self, string): if type(string) == unicode: return string.encode("utf-8") tempstring = unicode(string,"cp1252").encode("utf-8") @@ -121,7 +123,7 @@ class DomApiGeneral: class DomApi(DomApiGeneral): """This class provides a DOM-API for XML-Files from an SXW-Archive.""" - def __init__(self,xml_content,xml_styles): + def __init__(self, xml_content, xml_styles): DomApiGeneral.__init__(self) self.content_dom = xml.dom.minidom.parseString(xml_content) self.styles_dom = xml.dom.minidom.parseString(xml_styles) @@ -145,7 +147,7 @@ class DomApi(DomApiGeneral): for s in self.style_dict.keys(): self.style_properties_dict[s] = self.getStylePropertiesDict(s) - def updateWithPercents(self,dict,updatedict): + def updateWithPercents(self, dict, updatedict): """Sometimes you find values like "115%" in the style hierarchy.""" if not updatedict: # no style hierarchies for this style? => @@ -244,7 +246,7 @@ class DomApi(DomApiGeneral): def toxml(self): return self.content_dom.toxml(encoding="utf-8") - def getStylePropertiesDict(self,style_name): + def getStylePropertiesDict(self, style_name): res = {} if self.style_dict[style_name].hasAttribute("style:parent-style-name"): @@ -265,7 +267,7 @@ class PyOpenOffice(object): self.save_pict = save_pict self.images = {} - def oo_read(self,fname): + def oo_read(self, fname): z = zipfile.ZipFile(fname,"r") content = z.read('content.xml') style = z.read('styles.xml') @@ -281,7 +283,7 @@ class PyOpenOffice(object): z.close() return content,style - def oo_replace(self,content): + def oo_replace(self, content): regex = [ (r"]*/>", ""), (r"(.*?)]*/>", "$2"), @@ -290,7 +292,7 @@ class PyOpenOffice(object): content = re.sub(key, val, content) return content - def unpackNormalize(self,sourcefile): + def unpackNormalize(self, sourcefile): c,s = self.oo_read(sourcefile) c = self.oo_replace(c) dom = DomApi(c,s) diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py index 401cf88b418..43b452b82e2 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py @@ -52,7 +52,7 @@ if __name__<>'package': from lib.gui import * class About(unohelper.Base, XJobExecutor): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py index c65ba32e6bf..69e297ab4c0 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py @@ -64,7 +64,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): 'PDF' : 'pdf', 'OpenOffice': 'sxw', } - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" @@ -132,7 +132,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): self.win.addButton('btnCancel', -2 - 27 , -5 , 30 , 15, 'Cancel' ,actionListenerProc = self.btnCancel_clicked ) self.win.doModalDialog("lstResourceType", self.Kind.keys()[0]) - def btnSearch_clicked( self, oActionEvent ): + def btnSearch_clicked(self, oActionEvent): modelSelectedItem = self.win.getListBoxSelectedItem("lstmodel") if modelSelectedItem == "": return @@ -151,7 +151,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): for result in self.aSearchResult: self.lstResource.addItem(result[1],result[0]) - def _send_attachment( self, name, data, res_model, res_id ): + def _send_attachment(self, name, data, res_model, res_id): desktop = getDesktop() oDoc2 = desktop.getCurrentComponent() docinfo = oDoc2.getDocumentInfo() @@ -166,7 +166,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): return self.sock.execute( database, uid, self.password, 'ir.attachment', 'create', params ) - def send_attachment( self, model, resource_id ): + def send_attachment(self, model, resource_id): desktop = getDesktop() oDoc2 = desktop.getCurrentComponent() docinfo = oDoc2.getDocumentInfo() @@ -187,7 +187,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): data = read_data_from_file( get_absolute_file_path( url ) ) return self._send_attachment( os.path.basename( url ), data, model, resource_id ) - def btnOkWithoutInformation_clicked( self, oActionEvent ): + def btnOkWithoutInformation_clicked(self, oActionEvent): desktop = getDesktop() oDoc2 = desktop.getCurrentComponent() docinfo = oDoc2.getDocumentInfo() @@ -199,7 +199,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): res = self.send_attachment( docinfo.getUserFieldValue(3), docinfo.getUserFieldValue(2) ) self.win.endExecute() - def btnOkWithInformation_clicked(self,oActionEvent): + def btnOkWithInformation_clicked(self, oActionEvent): if self.win.getListBoxSelectedItem("lstResourceType") == "": ErrorDialog( "Please select resource type", "", "Selection ERROR" ) return @@ -221,7 +221,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): res = self.send_attachment( self.dModel[self.win.getListBoxSelectedItem('lstmodel')], resourceid ) self.win.endExecute() - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() def doc2pdf(self, strFile): @@ -262,7 +262,7 @@ class AddAttachment(unohelper.Base, XJobExecutor ): # Can be None if len(strFilterSubName) <= 0 return filename - def _MakePropertyValue(self, cName = "", uValue = u"" ): + def _MakePropertyValue(self, cName="", uValue=u"" ): oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" ) if cName: oPropertyValue.Name = cName diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py index cdc5c7553b1..3c76ac90207 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py @@ -59,7 +59,7 @@ if __name__<>"package": database="test" class Change( unohelper.Base, XJobExecutor ): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" @@ -107,7 +107,7 @@ class Change( unohelper.Base, XJobExecutor ): self.lstProtocol.addItem(i,self.lstProtocol.getItemCount() ) self.win.doModalDialog( "lstProtocol", protocol) - def btnNext_clicked(self,oActionEvent): + def btnNext_clicked(self, oActionEvent): global url aVal='' #aVal= Fetature used diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py index bb80c3ecd61..49844b4bfe3 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py @@ -63,7 +63,7 @@ if __name__<>"package": class ConvertBracesToField( unohelper.Base, XJobExecutor ): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" @@ -198,7 +198,7 @@ class ConvertBracesToField( unohelper.Base, XJobExecutor ): info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) self.logobj.log_write('ConvertBraceToField', LOG_ERROR, info) - def getRes(self,sock,sObject,sVar): + def getRes(self, sock, sObject, sVar): desktop=getDesktop() doc =desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() @@ -215,7 +215,7 @@ class ConvertBracesToField( unohelper.Base, XJobExecutor ): sObject = self.getRes(sock,res[myval]['relation'], sVar[sVar.find("/")+1:]) return sObject - def getBraces(self,aReportSyntex=[]): + def getBraces(self, aReportSyntex=None): desktop=getDesktop() doc = desktop.getCurrentComponent() aSearchString=[] diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py index 892061c56b4..ffa88a8cd06 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py @@ -57,7 +57,7 @@ if __name__<>"package": uid = 3 class ConvertFieldsToBraces( unohelper.Base, XJobExecutor ): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py index dd00f1719e1..293fee7388b 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py @@ -67,7 +67,7 @@ if __name__<>"package": class ExportToRML( unohelper.Base, XJobExecutor ): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py index ecdf13454dc..aaedb30e8fd 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py @@ -57,7 +57,7 @@ if __name__<>"package": uid = 3 class Expression(unohelper.Base, XJobExecutor ): - def __init__(self,sExpression="",sName="", bFromModify=False): + def __init__(self, sExpression="", sName="", bFromModify=False): LoginTest() if not loginstatus and __name__=="package": exit(1) @@ -75,7 +75,7 @@ class Expression(unohelper.Base, XJobExecutor ): self.win.doModalDialog("",None) - def btnOk_clicked( self, oActionEvent ): + def btnOk_clicked(self, oActionEvent): desktop=getDesktop() doc = desktop.getCurrentComponent() text = doc.Text @@ -105,7 +105,7 @@ class Expression(unohelper.Base, XJobExecutor ): else: ErrorDialog("Please Fill appropriate data in Name field or \nExpression field") - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() if __name__<>"package" and __name__=="__main__": diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py index 92044f78fe1..d480d683868 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py @@ -64,7 +64,7 @@ if __name__<>"package": class Fields(unohelper.Base, XJobExecutor ): - def __init__(self,sVariable="",sFields="",sDisplayName="",bFromModify=False): + def __init__(self, sVariable="", sFields="", sDisplayName="", bFromModify=False): LoginTest() if not loginstatus and __name__=="package": exit(1) @@ -177,7 +177,7 @@ class Fields(unohelper.Base, XJobExecutor ): ErrorDialog("Please insert user define field Field-1 or Field-4","Just go to File->Properties->User Define \nField-1 Eg. http://localhost:8069 \nOR \nField-4 Eg. account.invoice") self.win.endExecute() - def lstbox_selected(self,oItemEvent): + def lstbox_selected(self, oItemEvent): try: desktop=getDesktop() @@ -200,7 +200,7 @@ class Fields(unohelper.Base, XJobExecutor ): if self.bModify: self.win.setEditText("txtUName",self.sGDisplayName) - def getRes(self,sock ,sObject,sVar): + def getRes(self, sock, sObject, sVar): desktop=getDesktop() doc =desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() @@ -219,7 +219,7 @@ class Fields(unohelper.Base, XJobExecutor ): else: return sObject - def cmbVariable_selected(self,oItemEvent): + def cmbVariable_selected(self, oItemEvent): if self.count > 0 : try: desktop=getDesktop() @@ -246,7 +246,7 @@ class Fields(unohelper.Base, XJobExecutor ): info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) self.logobj.log_write('Fields', LOG_ERROR, info) - def btnOk_clicked( self, oActionEvent ): + def btnOk_clicked(self, oActionEvent): desktop=getDesktop() doc = desktop.getCurrentComponent() cursor = doc.getCurrentController().getViewCursor() @@ -281,7 +281,7 @@ class Fields(unohelper.Base, XJobExecutor ): else: ErrorDialog("Please Fill appropriate data in Name field \nor select perticular value from the list of fields") - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() if __name__<>"package" and __name__=="__main__": diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py index 2ccd8358c97..d93dc3521e4 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py @@ -66,7 +66,7 @@ if __name__<>'package': # class ModifyExistingReport(unohelper.Base, XJobExecutor): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" @@ -178,10 +178,10 @@ class ModifyExistingReport(unohelper.Base, XJobExecutor): self.win.endExecute() - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() - def btnDelete_clicked( self, oActionEvent ): + def btnDelete_clicked(self, oActionEvent): desktop=getDesktop() doc = desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py index 6022e44df7a..138c68b690e 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py @@ -66,7 +66,7 @@ if __name__<>"package": # # class NewReport(unohelper.Base, XJobExecutor): - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" @@ -99,7 +99,7 @@ class NewReport(unohelper.Base, XJobExecutor): self.win.addButton('btnCancel',-2 - 70 - 5 ,-5, 35,15,'Cancel' ,actionListenerProc = self.btnCancel_clicked ) self.win.doModalDialog("",None) - def btnOk_clicked(self,oActionEvent): + def btnOk_clicked(self, oActionEvent): desktop=getDesktop() doc = desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() @@ -107,7 +107,7 @@ class NewReport(unohelper.Base, XJobExecutor): self.logobj.log_write('Module Name',LOG_INFO, ':Module use in creating a report %s using database %s' % (self.aModuleName[self.lstModule.getSelectedItemPos()], database)) self.win.endExecute() - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() if __name__<>"package" and __name__=="__main__": diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py index 0eab6d1710c..50af718849e 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py @@ -64,7 +64,7 @@ if __name__<>"package": #class RepeatIn: class RepeatIn( unohelper.Base, XJobExecutor ): - def __init__(self,sObject="",sVariable="",sFields="",sDisplayName="",bFromModify=False): + def __init__(self, sObject="", sVariable="", sFields="", sDisplayName="", bFromModify=False): # Interface Design LoginTest() self.logobj=Logger() @@ -204,7 +204,7 @@ class RepeatIn( unohelper.Base, XJobExecutor ): ErrorDialog("Please Select Appropriate module" ,"Create new report from: \nOpenERP -> Open a New Report") self.win.endExecute() - def lstbox_selected(self,oItemEvent): + def lstbox_selected(self, oItemEvent): sItem=self.win.getListBoxSelectedItem("lstFields") sMain=self.aListRepeatIn[self.win.getListBoxSelectedItemPos("lstFields")] @@ -215,7 +215,7 @@ class RepeatIn( unohelper.Base, XJobExecutor ): self.win.setEditText("txtName",sMain[sMain.rfind("/")+1:]) self.win.setEditText("txtUName","|-."+sItem[sItem.rfind("/")+1:]+".-|") - def cmbVariable_selected(self,oItemEvent): + def cmbVariable_selected(self, oItemEvent): if self.count > 0 : @@ -290,7 +290,7 @@ class RepeatIn( unohelper.Base, XJobExecutor ): else: ErrorDialog("Please Fill appropriate data in Object Field or Name field \nor select perticular value from the list of fields") - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() if __name__<>"package" and __name__=="__main__": diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py index 3a6d799f8a5..dcc0aa6f632 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py @@ -74,7 +74,7 @@ class SendtoServer(unohelper.Base, XJobExecutor): 'HTML' : 'html' } - def __init__(self,ctx): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" @@ -138,10 +138,10 @@ class SendtoServer(unohelper.Base, XJobExecutor): self.win.doModalDialog("lstResourceType", self.Kind.keys()[0]) - def lstbox_selected(self,oItemEvent): + def lstbox_selected(self, oItemEvent): pass - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() def btnOk_clicked(self, oActionEvent): @@ -223,7 +223,7 @@ class SendtoServer(unohelper.Base, XJobExecutor): id=self.sock.execute(database, uid, self.password, 'ir.actions.report.xml' ,'create', params) return id - def getInverseFieldsRecord(self,nVal): + def getInverseFieldsRecord(self, nVal): desktop=getDesktop() doc = desktop.getCurrentComponent() count=0 diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py index 9b69e4a5c15..cb87d0fc5c7 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py @@ -59,7 +59,7 @@ if __name__<>"package": database="test" class ServerParameter( unohelper.Base, XJobExecutor ): - def __init__(self, aVal= None, sURL=""): + def __init__(self, aVal=None, sURL=""): self.module = "openerp_report" self.version = "0.1" desktop=getDesktop() @@ -116,7 +116,7 @@ class ServerParameter( unohelper.Base, XJobExecutor ): #self.win.doModalDialog("lstDatabase",docinfo.getUserFieldValue(2)) - def btnOk_clicked(self,oActionEvent): + def btnOk_clicked(self, oActionEvent): sLogin=self.win.getEditText("txtLoginName") sPassword=self.win.getEditText("txtPassword") @@ -158,10 +158,10 @@ class ServerParameter( unohelper.Base, XJobExecutor ): self.win.endExecute() - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() - def btnPrevious_clicked(self,oActionEvent): + def btnPrevious_clicked(self, oActionEvent): self.win.endExecute() Change(None) self.win.endExecute() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py index 73146f1b68a..576bc0c3134 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py @@ -61,7 +61,7 @@ if __name__<>"package": class AddLang(unohelper.Base, XJobExecutor ): - def __init__(self,sVariable="",sFields="",sDisplayName="",bFromModify=False): + def __init__(self, sVariable="", sFields="", sDisplayName="", bFromModify=False): LoginTest() if not loginstatus and __name__=="package": exit(1) @@ -157,7 +157,7 @@ class AddLang(unohelper.Base, XJobExecutor ): ErrorDialog("Please insert user define field Field-1 or Field-4","Just go to File->Properties->User Define \nField-1 Eg. http://localhost:8069 \nOR \nField-4 Eg. account.invoice") self.win.endExecute() - def lstbox_selected(self,oItemEvent): + def lstbox_selected(self, oItemEvent): try: desktop=getDesktop() @@ -183,7 +183,7 @@ class AddLang(unohelper.Base, XJobExecutor ): if self.bModify: self.win.setEditText("txtUName",self.sGDisplayName) - def getRes(self,sock ,sObject,sVar): + def getRes(self, sock, sObject, sVar): desktop=getDesktop() doc =desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() @@ -203,7 +203,7 @@ class AddLang(unohelper.Base, XJobExecutor ): return sObject - def cmbVariable_selected(self,oItemEvent): + def cmbVariable_selected(self, oItemEvent): if self.count > 0 : try: desktop=getDesktop() @@ -229,7 +229,7 @@ class AddLang(unohelper.Base, XJobExecutor ): except: import traceback;traceback.print_exc() - def btnOk_clicked( self, oActionEvent ): + def btnOk_clicked(self, oActionEvent): self.bOkay = True desktop=getDesktop() doc = desktop.getCurrentComponent() @@ -263,7 +263,7 @@ class AddLang(unohelper.Base, XJobExecutor ): else: ErrorDialog("Please Fill appropriate data in Name field \nor select perticular value from the list of fields") - def btnCancel_clicked( self, oActionEvent ): + def btnCancel_clicked(self, oActionEvent): self.win.endExecute() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py index c0a3e5b5d63..cb86f5f429a 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py @@ -48,7 +48,7 @@ if __name__<>"package": from gui import * class ErrorDialog: - def __init__(self,sErrorMsg, sErrorHelpMsg="",sTitle="Error Message"): + def __init__(self, sErrorMsg, sErrorHelpMsg="", sTitle="Error Message"): self.win = DBModalDialog(50, 50, 150, 90, sTitle) self.win.addFixedText("lblErrMsg", 5, 5, 190, 25, sErrorMsg) self.win.addFixedText("lblErrHelpMsg", 5, 30, 190, 25, sErrorHelpMsg) diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py index 29f1cd87e46..1b614224147 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py @@ -59,7 +59,13 @@ if __name__<>"package": database="test" uid = 1 -def genTree(object,aList,insField,host,level=3, ending=[], ending_excl=[], recur=[], root='', actualroot=""): +def genTree(object, aList, insField, host, level=3, ending=None, ending_excl=None, recur=None, root='', actualroot=""): + if ending is None: + ending = [] + if ending_excl is None: + ending_excl = [] + if recur is None: + recur = [] try: global url sock=RPCSession(url) @@ -79,7 +85,7 @@ def genTree(object,aList,insField,host,level=3, ending=[], ending_excl=[], recur info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) obj.log_write('Function', LOG_ERROR, info) -def VariableScope(oTcur,insVariable,aObjectList,aComponentAdd,aItemList,sTableName=""): +def VariableScope(oTcur, insVariable, aObjectList, aComponentAdd, aItemList, sTableName=""): if sTableName.find(".") != -1: for i in range(len(aItemList)): if aComponentAdd[i]==sTableName: @@ -96,7 +102,7 @@ def VariableScope(oTcur,insVariable,aObjectList,aComponentAdd,aItemList,sTableNa if aObjectList[j][:aObjectList[j].find("(")] == sLVal and sLVal!="": insVariable.append(aObjectList[j]) -def getList(aObjectList,host,count): +def getList(aObjectList, host, count): desktop=getDesktop() doc =desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() @@ -128,7 +134,7 @@ def getList(aObjectList,host,count): else: aObjectList.append("List of " + docinfo.getUserFieldValue(3)) -def getRelation(sRelName, sItem, sObjName, aObjectList, host ): +def getRelation(sRelName, sItem, sObjName, aObjectList, host): global url sock=RPCSession(url) global passwd @@ -143,7 +149,7 @@ def getRelation(sRelName, sItem, sObjName, aObjectList, host ): getRelation(res[k]['relation'], sItem[sItem.find(".")+1:], sObjName,aObjectList,host) -def getPath(sPath,sMain): +def getPath(sPath, sMain): desktop=getDesktop() doc =desktop.getCurrentComponent() oParEnum = doc.getTextFields().createEnumeration() @@ -161,7 +167,7 @@ def getPath(sPath,sMain): getPath(sPath, sMain) return sPath -def EnumDocument(aItemList,aComponentAdd): +def EnumDocument(aItemList, aComponentAdd): desktop = getDesktop() parent="" bFlag = False @@ -183,7 +189,7 @@ def EnumDocument(aItemList,aComponentAdd): aItemList.append( templist ) aComponentAdd.append( parent ) -def getChildTable(oPar,aItemList,aComponentAdd,sTableName=""): +def getChildTable(oPar, aItemList, aComponentAdd, sTableName=""): sNames = oPar.getCellNames() bEmptyTableFlag=True for val in sNames: @@ -229,7 +235,7 @@ def getChildTable(oPar,aItemList,aComponentAdd,sTableName=""): aComponentAdd.append(sTableName+"."+oPar.Name) return 0 -def getRecersiveSection(oCurrentSection,aSectionList): +def getRecersiveSection(oCurrentSection, aSectionList): desktop=getDesktop() doc =desktop.getCurrentComponent() oParEnum=doc.getText().createEnumeration() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py index 2aab8596862..b03c1360cad 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py @@ -39,7 +39,7 @@ def log_detail(self): logger.setLevel(logging.INFO) class Logger(object): - def log_write(self,name,level,msg): + def log_write(self, name, level, msg): log = logging.getLogger(name) getattr(log,level)(msg) diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py index f7c7f636485..5d6f8ca6dbc 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py @@ -52,7 +52,7 @@ class RPCGateway(object): class RPCSession(object): - def __init__(self,url): + def __init__(self, url): m = re.match('^(http[s]?://|socket://)([\w.\-]+):(\d{1,5})$', url or '') @@ -152,7 +152,7 @@ class XMLRPCGateway(RPCGateway): return res - def execute(self, sDatabase,UID,sPassword,obj, method, *args): + def execute(self, sDatabase, UID, sPassword, obj, method, *args): global rpc_url sock = xmlrpclib.ServerProxy(rpc_url + 'object') diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py index ef22a3a0d51..53dc81f5bc3 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py @@ -21,19 +21,19 @@ ############################################################################## import urllib -def get_absolute_file_path( url ): +def get_absolute_file_path(url): url_unquoted = urllib.unquote(url) return os.name == 'nt' and url_unquoted[1:] or url_unquoted # This function reads the content of a file and return it to the caller -def read_data_from_file( filename ): +def read_data_from_file(filename): fp = file( filename, "rb" ) data = fp.read() fp.close() return data # This function writes the content to a file -def write_data_to_file( filename, data ): +def write_data_to_file(filename, data): fp = file( filename, 'wb' ) fp.write( data ) fp.close() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py index fc3d6672b79..41f00de7183 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py @@ -61,7 +61,7 @@ if __name__<>"package": uid = 3 class modify(unohelper.Base, XJobExecutor ): - def __init__( self, ctx ): + def __init__(self, ctx): self.ctx = ctx self.module = "openerp_report" self.version = "0.1" diff --git a/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py b/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py index 8954aa8d7a8..ac2b2fb2881 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py @@ -10,7 +10,11 @@ import time sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/object') -def get(object, level=3, ending=[], ending_excl=[], recur=[], root=''): +def get(object, level=3, ending=None, ending_excl=None, recur=None, root=''): + if ending is None: + ending = [] + if ending_excl is None: + ending_excl = [] res = sock.execute('terp', 3, 'admin', 'account.invoice', 'fields_get') key = res.keys() key.sort() diff --git a/addons/base_setup/base_setup.py b/addons/base_setup/base_setup.py index c10dee7b14b..3d624e9f33a 100644 --- a/addons/base_setup/base_setup.py +++ b/addons/base_setup/base_setup.py @@ -84,7 +84,7 @@ def _lang_get(self, cr, uid, context=None): res = [(r['code'], r['name']) for r in res] return res -def _tz_get(self,cr,uid, context=None): +def _tz_get(self, cr, uid, context=None): return [(x, x) for x in pytz.all_timezones] class user_preferences_config(osv.osv_memory): diff --git a/addons/base_synchro/base_synchro_obj.py b/addons/base_synchro/base_synchro_obj.py index 78df80591bc..f35275b3c44 100644 --- a/addons/base_synchro/base_synchro_obj.py +++ b/addons/base_synchro/base_synchro_obj.py @@ -65,10 +65,12 @@ class base_synchro_obj(osv.osv): # Return a list of changes: [ (date, id) ] # - def get_ids(self, cr, uid, object, dt, domain=[], context=None): - return self._get_ids(cr, uid, object, dt, domain, context=context) + def get_ids(self, cr, uid, object, dt, domain=None, context=None): + return self._get_ids(cr, uid, object, dt, domain=domain, context=context) - def _get_ids(self, cr, uid, object, dt, domain=[], context=None): + def _get_ids(self, cr, uid, object, dt, domain=None, context=None): + if domain is None: + domain = [] result = [] if dt: domain2 = domain+[('write_date','>=',dt)] diff --git a/addons/base_vat/__init__.py b/addons/base_vat/__init__.py index 1d7c143b7dc..2331d5661c1 100644 --- a/addons/base_vat/__init__.py +++ b/addons/base_vat/__init__.py @@ -22,4 +22,4 @@ import res_company import base_vat -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_vat/res_company.py b/addons/base_vat/res_company.py index e7641db9c68..1c63aa20f07 100644 --- a/addons/base_vat/res_company.py +++ b/addons/base_vat/res_company.py @@ -29,4 +29,4 @@ class res_company_vat (osv.osv): "rather than via a simple format validation (checksum)."), } - \ No newline at end of file + diff --git a/addons/caldav/caldav_node.py b/addons/caldav/caldav_node.py index 71e9bdc2468..211fcd3da95 100644 --- a/addons/caldav/caldav_node.py +++ b/addons/caldav/caldav_node.py @@ -42,7 +42,7 @@ class node_calendar_collection(nodes.node_dir): DAV_M_NS = dict_merge2(nodes.node_dir.DAV_M_NS, { "http://calendarserver.org/ns/" : '_get_dav', } ) - def _file_get(self,cr, nodename=False): + def _file_get(self, cr, nodename=False): return [] def _child_get(self, cr, name=False, parent_id=False, domain=None): @@ -99,7 +99,7 @@ class node_calendar_res_col(nodes.node_res_obj): DAV_M_NS = dict_merge2(nodes.node_res_obj.DAV_M_NS, { "http://calendarserver.org/ns/" : '_get_dav', } ) - def _file_get(self,cr, nodename=False): + def _file_get(self, cr, nodename=False): return [] def _child_get(self, cr, name=False, parent_id=False, domain=None): @@ -180,7 +180,7 @@ class node_calendar(nodes.node_class): http_options = { 'DAV': ['calendar-access'] } - def __init__(self,path, parent, context, calendar): + def __init__(self, path, parent, context, calendar): super(node_calendar,self).__init__(path, parent,context) self.calendar_id = calendar.id self.mimetype = 'application/x-directory' @@ -271,7 +271,7 @@ class node_calendar(nodes.node_class): def children(self, cr, domain=None): return self._child_get(cr, domain=domain) - def child(self,cr, name, domain=None): + def child(self, cr, name, domain=None): res = self._child_get(cr, name, domain=domain) if res: return res[0] @@ -353,16 +353,16 @@ class node_calendar(nodes.node_class): return None - def set_data(self, cr, data, fil_obj = None): + def set_data(self, cr, data, fil_obj=None): uid = self.context.uid calendar_obj = self.context._dirobj.pool.get('basic.calendar') res = calendar_obj.import_cal(cr, uid, data, self.calendar_id) return res - def get_data_len(self, cr, fil_obj = None): + def get_data_len(self, cr, fil_obj=None): return self.content_length - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'calendar-%d' % (self.calendar_id,) def rmcol(self, cr): @@ -441,7 +441,7 @@ class res_node_calendar(nodes.node_class): http_options = { 'DAV': ['calendar-access'] } - def __init__(self,path, parent, context, res_obj, res_model=None, res_id=None): + def __init__(self, path, parent, context, res_obj, res_model=None, res_id=None): super(res_node_calendar,self).__init__(path, parent, context) self.mimetype = 'text/calendar' self.create_date = parent.create_date @@ -474,10 +474,10 @@ class res_node_calendar(nodes.node_class): def _get_caldav_calendar_data(self, cr): return self.get_data(cr) - def get_data_len(self, cr, fil_obj = None): + def get_data_len(self, cr, fil_obj=None): return self.content_length - def set_data(self, cr, data, fil_obj = None): + def set_data(self, cr, data, fil_obj=None): uid = self.context.uid context = self.context.context.copy() context.update(self.dctx) @@ -486,7 +486,7 @@ class res_node_calendar(nodes.node_class): res = calendar_obj.import_cal(cr, uid, data, self.calendar_id, context=context) return res - def _get_ttag(self,cr): + def _get_ttag(self, cr): res = False if self.model and self.res_id: res = '%s_%d' % (self.model, self.res_id) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 4ebb0b4796d..a12c1662c0f 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -331,7 +331,9 @@ class crm_case(crm_base): And object that inherit (orm inheritance) from a class the overwrite copy """ - def stage_find(self, cr, uid, section_id, domain=[], order='sequence'): + def stage_find(self, cr, uid, section_id, domain=None, order='sequence'): + if domain is None: + domain = [] domain = list(domain) if section_id: domain.append(('section_ids', '=', section_id)) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index b17fa31ac91..a93ae8b4de2 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -239,7 +239,7 @@ class crm_lead(crm_case, osv.osv): def on_change_optout(self, cr, uid, ids, optout): return {'value':{'optout':optout,'optin':False}} - def onchange_stage_id(self, cr, uid, ids, stage_id, context={}): + def onchange_stage_id(self, cr, uid, ids, stage_id, context=None): if not stage_id: return {'value':{}} stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context) diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index fb6b8f90bda..1ee431cd77a 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -157,7 +157,7 @@ class crm_claim(crm.crm_case, osv.osv): self.write(cr, uid, [res_id], vals, context=context) return res_id - def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None): + def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None): if isinstance(ids, (str, int, long)): ids = [ids] diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py index 97ed007f456..f60e0e112b3 100644 --- a/addons/crm_helpdesk/crm_helpdesk.py +++ b/addons/crm_helpdesk/crm_helpdesk.py @@ -112,7 +112,7 @@ class crm_helpdesk(crm.crm_case, osv.osv): self.write(cr, uid, [res_id], vals, context) return res_id - def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None): + def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None): if isinstance(ids, (str, int, long)): ids = [ids] diff --git a/addons/crm_profiling/crm_profiling.py b/addons/crm_profiling/crm_profiling.py index 587ddbe0b52..83d19b14d97 100644 --- a/addons/crm_profiling/crm_profiling.py +++ b/addons/crm_profiling/crm_profiling.py @@ -77,7 +77,7 @@ def _get_parents(cr, uid, ids): return ids_to_check -def test_prof(cr, uid, seg_id, pid, answers_ids = []): +def test_prof(cr, uid, seg_id, pid, answers_ids=None): """ return True if the partner pid fetch the segmentation rule seg_id @param cr: the current row, from the database cursor, diff --git a/addons/delivery/wizard/delivery_sale_order.py b/addons/delivery/wizard/delivery_sale_order.py index 80b3431f2a7..a8339ce800a 100644 --- a/addons/delivery/wizard/delivery_sale_order.py +++ b/addons/delivery/wizard/delivery_sale_order.py @@ -44,7 +44,7 @@ class make_delivery(osv.osv_memory): return res - def view_init(self, cr , uid , fields, context=None): + def view_init(self, cr, uid, fields, context=None): if context is None: context = {} order_obj = self.pool.get('sale.order') diff --git a/addons/document/content_index.py b/addons/document/content_index.py index 64b480ee736..88767f7fed9 100644 --- a/addons/document/content_index.py +++ b/addons/document/content_index.py @@ -51,7 +51,7 @@ class indexer(object): return mts[0] return None - def indexContent(self, content, filename=None, realfile = None): + def indexContent(self, content, filename=None, realfile=None): """ Use either content or the real file, to index. Some parsers will work better with the actual content, others parse a file easier. Try the @@ -95,10 +95,10 @@ class indexer(object): raise NhException('No appropriate method to index file') - def _doIndexContent(self,content): + def _doIndexContent(self, content): raise NhException("Content not handled here") - def _doIndexFile(self,fpath): + def _doIndexFile(self, fpath): raise NhException("Content not handled here") def __repr__(self): @@ -136,7 +136,7 @@ class contentIndex(object): if not f: raise Exception("Your indexer should at least suport a mimetype or extension") - def doIndex(self, content, filename=None, content_type=None, realfname = None, debug=False): + def doIndex(self, content, filename=None, content_type=None, realfname=None, debug=False): fobj = None fname = None mime = None diff --git a/addons/document/document.py b/addons/document/document.py index 9ea7f97a321..5e95eee241c 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -146,7 +146,7 @@ class document_file(osv.osv): _sql_constraints = [ # filename_uniq is not possible in pure SQL ] - def _check_duplication(self, cr, uid, vals, ids=[], op='create'): + def _check_duplication(self, cr, uid, vals, ids=None, op='create'): name = vals.get('name', False) parent_id = vals.get('parent_id', False) res_model = vals.get('res_model', False) diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py index d09d2cc86d5..33f1da1125b 100644 --- a/addons/document/document_directory.py +++ b/addons/document/document_directory.py @@ -69,7 +69,7 @@ class document_directory(osv.osv): } - def _get_root_directory(self, cr,uid, context=None): + def _get_root_directory(self, cr, uid, context=None): objid=self.pool.get('ir.model.data') try: mid = objid._get_id(cr, uid, 'document', 'dir_root') @@ -224,7 +224,7 @@ class document_directory(osv.osv): pass return res - def _locate_child(self, cr, uid, root_id, uri,nparent, ncontext): + def _locate_child(self, cr, uid, root_id, uri, nparent, ncontext): """ try to locate the node in uri, Return a tuple (node_dir, remaining_path) """ @@ -237,7 +237,7 @@ class document_directory(osv.osv): default.update({'name': name+ " (copy)"}) return super(document_directory,self).copy(cr, uid, id, default, context=context) - def _check_duplication(self, cr, uid, vals, ids=[], op='create'): + def _check_duplication(self, cr, uid, vals, ids=None, op='create'): name=vals.get('name',False) parent_id=vals.get('parent_id',False) ressource_parent_type_id=vals.get('ressource_parent_type_id',False) diff --git a/addons/document/nodes.py b/addons/document/nodes.py index ee89f3d4c6c..21e5029bd39 100644 --- a/addons/document/nodes.py +++ b/addons/document/nodes.py @@ -104,7 +104,7 @@ class node_context(object): def get(self, name, default=None): return self.context.get(name, default) - def get_uri(self, cr, uri): + def get_uri(self, cr, uri): """ Although this fn passes back to doc.dir, it is needed since it is a potential caching point. """ @@ -253,7 +253,7 @@ class node_class(object): print "node_class.children()" return [] #stub - def child(self,cr, name, domain=None): + def child(self, cr, name, domain=None): print "node_class.child()" return None @@ -271,7 +271,7 @@ class node_class(object): print "node_class.path_get()" return False - def get_data(self,cr): + def get_data(self, cr): raise TypeError('no data for %s'% self.type) def open_data(self, cr, mode): @@ -288,10 +288,10 @@ class node_class(object): """ raise TypeError('no data for %s' % self.type) - def _get_storage(self,cr): + def _get_storage(self, cr): raise RuntimeError("no storage for base class") - def get_etag(self,cr): + def get_etag(self, cr): """ Get a tag, unique per object + modification. see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """ @@ -435,7 +435,9 @@ class node_database(node_class): """ our_type = 'database' - def __init__(self, path=[], parent=False, context=None): + def __init__(self, path=None, parent=False, context=None): + if path is None: + path = [] super(node_database,self).__init__(path, parent, context) self.unixperms = 040750 self.uidperms = 5 @@ -478,11 +480,11 @@ class node_database(node_class): return res - def _file_get(self,cr, nodename=False): + def _file_get(self, cr, nodename=False): res = [] return res - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'db-%s' % cr.dbname def mkdosname(company_name, default='noname'): @@ -694,7 +696,7 @@ class node_dir(node_database): fnode.set_data(cr, data, fil) return fnode - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'dir-%d' % self.dir_id def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): @@ -803,7 +805,7 @@ class node_res_dir(node_class): def children(self, cr, domain=None): return self._child_get(cr, domain=domain) - def child(self,cr, name, domain=None): + def child(self, cr, name, domain=None): res = self._child_get(cr, name, domain=domain) if res: return res[0] @@ -879,7 +881,7 @@ class node_res_dir(node_class): res.append(self.res_obj_class(res_name, self.dir_id, self, self.context, self.res_model, bo)) return res - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'rdir-%d' % self.dir_id class node_res_obj(node_class): @@ -890,7 +892,7 @@ class node_res_obj(node_class): node_dirs (with limited domain). """ our_type = 'collection' - def __init__(self, path, dir_id, parent, context, res_model, res_bo, res_id = None): + def __init__(self, path, dir_id, parent, context, res_model, res_bo, res_id=None): super(node_res_obj,self).__init__(path, parent,context) assert parent #todo: more info from dirr @@ -959,7 +961,7 @@ class node_res_obj(node_class): return res[0] return None - def _file_get(self,cr, nodename=False): + def _file_get(self, cr, nodename=False): res = [] is_allowed = self.check_perms((nodename and 1) or 5) if not is_allowed: @@ -1161,7 +1163,7 @@ class node_res_obj(node_class): fnode.set_data(cr, data, fil) return fnode - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'rodir-%d-%d' % (self.dir_id, self.res_id) node_res_dir.res_obj_class = node_res_obj @@ -1263,7 +1265,7 @@ class node_file(node_class): else: self.path = dirpath[0] - def get_data(self, cr, fil_obj = None): + def get_data(self, cr, fil_obj=None): """ Retrieve the data for some file. fil_obj may optionally be specified, and should be a browse object for the file. This is useful when the caller has already initiated @@ -1279,14 +1281,14 @@ class node_file(node_class): stobj = self.context._dirobj.pool.get('document.storage') return stobj.get_data(cr, self.context.uid,stor, self,self.context.context, fil_obj) - def get_data_len(self, cr, fil_obj = None): + def get_data_len(self, cr, fil_obj=None): # TODO: verify with the storage object! bin_size = self.context.context.get('bin_size', False) if bin_size and not self.content_length: self.content_length = fil_obj.db_datas return self.content_length - def set_data(self, cr, data, fil_obj = None): + def set_data(self, cr, data, fil_obj=None): """ Store data at some file. fil_obj may optionally be specified, and should be a browse object for the file. This is useful when the caller has already initiated @@ -1300,7 +1302,7 @@ class node_file(node_class): stobj = self.context._dirobj.pool.get('document.storage') return stobj.set_data(cr, self.context.uid,stor, self, data, self.context.context, fil_obj) - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'file-%d' % self.file_id def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): @@ -1363,7 +1365,7 @@ class node_file(node_class): class node_content(node_class): our_type = 'content' - def __init__(self, path, parent, context, cnt, dctx = None, act_id=None): + def __init__(self, path, parent, context, cnt, dctx=None, act_id=None): super(node_content,self).__init__(path, parent,context) self.cnt_id = cnt.id self.create_date = False @@ -1383,7 +1385,7 @@ class node_content(node_class): self.dctx.update(dctx) self.act_id = act_id - def fill_fields(self, cr, dctx = None): + def fill_fields(self, cr, dctx=None): """ Try to read the object and fill missing fields, like mimetype, dates etc. This function must be different from the constructor, because @@ -1397,7 +1399,7 @@ class node_content(node_class): self.mimetype = str(res[0][0]) - def get_data(self, cr, fil_obj = None): + def get_data(self, cr, fil_obj=None): cntobj = self.context._dirobj.pool.get('document.directory.content') if not self.check_perms(4): raise IOError(errno.EPERM, "Permission denied") @@ -1427,7 +1429,7 @@ class node_content(node_class): return nodefd_content(self, cr, mode, ctx) - def get_data_len(self, cr, fil_obj = None): + def get_data_len(self, cr, fil_obj=None): # FIXME : here, we actually generate the content twice!! # we should have cached the generated content, but it is # not advisable to do keep it in memory, until we have a cache @@ -1436,7 +1438,7 @@ class node_content(node_class): self.get_data(cr,fil_obj) return self.content_length - def set_data(self, cr, data, fil_obj = None): + def set_data(self, cr, data, fil_obj=None): cntobj = self.context._dirobj.pool.get('document.directory.content') if not self.check_perms(2): raise IOError(errno.EPERM, "Permission denied") @@ -1445,7 +1447,7 @@ class node_content(node_class): ctx.update(self.dctx) return cntobj.process_write(cr, self.context.uid, self, data, ctx) - def _get_ttag(self,cr): + def _get_ttag(self, cr): return 'cnt-%d%s' % (self.cnt_id,(self.act_id and ('-' + str(self.act_id))) or '') def get_dav_resourcetype(self, cr): diff --git a/addons/document/odt2txt.py b/addons/document/odt2txt.py old mode 100755 new mode 100644 index 9ca9b6e596f..8a3dc59d9ed --- a/addons/document/odt2txt.py +++ b/addons/document/odt2txt.py @@ -24,11 +24,11 @@ import sys, zipfile, xml.dom.minidom import StringIO class OpenDocumentTextFile : - def __init__ (self, filepath) : + def __init__ (self, filepath): zip = zipfile.ZipFile(filepath) self.content = xml.dom.minidom.parseString(zip.read("content.xml")) - def toString (self) : + def toString (self): """ Converts the document to a string. """ buffer = u"" for val in ["text:p", "text:h", "text:list"]: @@ -36,7 +36,7 @@ class OpenDocumentTextFile : buffer += self.textToString(paragraph) + "\n" return buffer - def textToString(self, element) : + def textToString(self, element): buffer = u"" for node in element.childNodes : if node.nodeType == xml.dom.Node.TEXT_NODE : diff --git a/addons/document/std_index.py b/addons/document/std_index.py index e153d018bf0..eb1da1a86e9 100644 --- a/addons/document/std_index.py +++ b/addons/document/std_index.py @@ -38,7 +38,7 @@ def _to_unicode(s): except UnicodeError: return s -def textToString(element) : +def textToString(element): buffer = u"" for node in element.childNodes : if node.nodeType == xml.dom.Node.TEXT_NODE : @@ -55,7 +55,7 @@ class TxtIndex(indexer): def _getExtensions(self): return ['.txt', '.py'] - def _doIndexContent(self,content): + def _doIndexContent(self, content): return content cntIndex.register(TxtIndex()) @@ -67,7 +67,7 @@ class PptxIndex(indexer): def _getExtensions(self): return ['.pptx'] - def _doIndexFile(self,fname): + def _doIndexFile(self, fname): def toString () : """ Converts the document to a string. """ buffer = u"" @@ -95,7 +95,7 @@ class DocIndex(indexer): def _getExtensions(self): return ['.doc'] - def _doIndexFile(self,fname): + def _doIndexFile(self, fname): try: pop = Popen(['antiword', fname], shell=False, stdout=PIPE) (data, _) = pop.communicate() @@ -115,7 +115,7 @@ class DocxIndex(indexer): def _getExtensions(self): return ['.docx'] - def _doIndexFile(self,fname): + def _doIndexFile(self, fname): zip = zipfile.ZipFile(fname) content = xml.dom.minidom.parseString(zip.read("word/document.xml")) def toString () : @@ -140,7 +140,7 @@ class XlsxIndex(indexer): def _getExtensions(self): return ['.xlsx'] - def _doIndexFile(self,fname): + def _doIndexFile(self, fname): zip = zipfile.ZipFile(fname) content = xml.dom.minidom.parseString(zip.read("xl/sharedStrings.xml")) def toString () : @@ -164,7 +164,7 @@ class PdfIndex(indexer): def _getExtensions(self): return ['.pdf'] - def _doIndexFile(self,fname): + def _doIndexFile(self, fname): pop = Popen(['pdftotext', '-enc', 'UTF-8', '-nopgbrk', fname, '-'], shell=False, stdout=PIPE) (data, _) = pop.communicate() return _to_unicode(data) @@ -180,7 +180,7 @@ class ImageNoIndex(indexer): return [] #return ['.png','.jpg','.gif','.jpeg','.bmp','.tiff'] - def _doIndexContent(self,content): + def _doIndexContent(self, content): return 'image' diff --git a/addons/document_webdav/document_webdav.py b/addons/document_webdav/document_webdav.py index da463c9eb1b..0cc4c919ff2 100644 --- a/addons/document_webdav/document_webdav.py +++ b/addons/document_webdav/document_webdav.py @@ -57,7 +57,7 @@ class document_davdir(osv.osv): # TODO group return - def _locate_child(self, cr, uid, root_id, uri,nparent, ncontext): + def _locate_child(self, cr, uid, root_id, uri, nparent, ncontext): """ try to locate the node in uri, Return a tuple (node_dir, remaining_path) """ diff --git a/addons/document_webdav/redirect.py b/addons/document_webdav/redirect.py index 7bc0883f9e8..7f419fadf52 100644 --- a/addons/document_webdav/redirect.py +++ b/addons/document_webdav/redirect.py @@ -30,7 +30,7 @@ class RedirectHTTPHandler(HttpLogHandler, FixSendError, HttpOptions, HTTPHandler _HTTP_OPTIONS = { 'Allow': ['OPTIONS', 'GET', 'HEAD', 'PROPFIND'] } redirect_paths = {} - def __init__(self,request, client_address, server): + def __init__(self, request, client_address, server): HTTPHandler.__init__(self,request,client_address,server) def send_head(self): diff --git a/addons/document_webdav/test_davclient.py b/addons/document_webdav/test_davclient.py old mode 100755 new mode 100644 index 3c20cfed5b8..306a058c574 --- a/addons/document_webdav/test_davclient.py +++ b/addons/document_webdav/test_davclient.py @@ -682,7 +682,7 @@ class DAVClient(object): assert d2 == d, "Data does not match" return ctype, rrange, d - def gd_put(self, path, body=None, srcpath=None, mime=None, noclobber=False, ): + def gd_put(self, path, body=None, srcpath=None, mime=None, noclobber=False): """ HTTP PUT @param noclobber will prevent overwritting a resource (If-None-Match) @param mime will set the content-type diff --git a/addons/document_webdav/webdav.py b/addons/document_webdav/webdav.py index baa394e94a1..8ad1932a317 100644 --- a/addons/document_webdav/webdav.py +++ b/addons/document_webdav/webdav.py @@ -236,7 +236,7 @@ def mk_prop_response(self, uri, good_props, bad_props, doc): return re -def mk_propname_response(self,uri,propnames,doc): +def mk_propname_response(self, uri, propnames, doc): """ make a new result element for a PROPNAME request This will simply format the propnames list. diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py index ae75d0b80fc..5218f55b396 100644 --- a/addons/document_webdav/webdav_server.py +++ b/addons/document_webdav/webdav_server.py @@ -81,7 +81,7 @@ class DAVHandler(HttpOptions, FixSendError, DAVRequestHandler): 'DELETE', 'TRACE', 'REPORT', ] } - def get_userinfo(self,user,pw): + def get_userinfo(self, user, pw): return False def _log(self, message): @@ -167,7 +167,7 @@ class DAVHandler(HttpOptions, FixSendError, DAVRequestHandler): self.close_connection = 1 DAVRequestHandler.send_header(self, key, value) - def send_body(self, DATA, code = None, msg = None, desc = None, ctype='application/octet-stream', headers=None): + def send_body(self, DATA, code=None, msg=None, desc=None, ctype='application/octet-stream', headers=None): if headers and 'Connection' in headers: pass elif self.request_version in ('HTTP/1.0', 'HTTP/0.9'): @@ -441,10 +441,10 @@ class dummy_dav_interface(object): def __init__(self, parent): self.parent = parent - def get_propnames(self,uri): + def get_propnames(self, uri): return self.PROPS - def get_prop(self,uri,ns,propname): + def get_prop(self, uri, ns, propname): if self.M_NS.has_key(ns): prefix=self.M_NS[ns] else: @@ -460,10 +460,10 @@ class dummy_dav_interface(object): def get_data(self, uri, range=None): raise DAV_NotFound - def _get_dav_creationdate(self,uri): + def _get_dav_creationdate(self, uri): return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) - def _get_dav_getlastmodified(self,uri): + def _get_dav_getlastmodified(self, uri): return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) def _get_dav_displayname(self, uri): diff --git a/addons/email_template/html2text.py b/addons/email_template/html2text.py old mode 100755 new mode 100644 index 745381850e3..9cb3a3fe5ac --- a/addons/email_template/html2text.py +++ b/addons/email_template/html2text.py @@ -158,7 +158,7 @@ class _html2text(sgmllib.SGMLParser): self.abbr_list = {} # stack of abbreviations to write later self.baseurl = baseurl - def outtextf(self, s): + def outtextf(self, s): self.outtext += s def close(self): @@ -338,7 +338,7 @@ class _html2text(sgmllib.SGMLParser): def pbr(self): if self.p_p == 0: self.p_p = 1 - def p(self): self.p_p = 2 + def p(self): def o(self, data, puredata=0, force=0): if self.abbr_data is not None: self.abbr_data += data @@ -411,7 +411,8 @@ class _html2text(sgmllib.SGMLParser): if r'\/script>' in data: self.quiet -= 1 self.o(data, 1) - def unknown_decl(self, data): pass + def unknown_decl(self, data): + pass def wrapwrite(text): sys.stdout.write(text.encode('utf8')) diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py index ef4572429a1..0338c22870c 100644 --- a/addons/email_template/wizard/mail_compose_message.py +++ b/addons/email_template/wizard/mail_compose_message.py @@ -27,7 +27,7 @@ from tools.translate import _ import tools -def _reopen(self,res_id,model): +def _reopen(self, res_id, model): return {'type': 'ir.actions.act_window', 'view_mode': 'form', 'view_type': 'form', diff --git a/addons/event/event.py b/addons/event/event.py index 133d29281f1..a66c73dc909 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -66,7 +66,7 @@ class event_event(osv.osv): res.append((record['id'], name)) return res - def _name_get_fnc(self, cr, uid, ids,prop,unknow, context=None): + def _name_get_fnc(self, cr, uid, ids, prop, unknow, context=None): res = self.name_get(cr, uid, ids, context=context) return dict(res) diff --git a/addons/event/report/__init__.py b/addons/event/report/__init__.py index 1c60e2715df..4f2516e5615 100644 --- a/addons/event/report/__init__.py +++ b/addons/event/report/__init__.py @@ -21,4 +21,4 @@ import report_event_registration -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/event/res_partner.py b/addons/event/res_partner.py index 1d5582f7929..3952f2f82b6 100644 --- a/addons/event/res_partner.py +++ b/addons/event/res_partner.py @@ -32,4 +32,4 @@ class res_partner(osv.osv): res_partner() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/event/wizard/event_confirm.py b/addons/event/wizard/event_confirm.py index e21d523bb12..e001aac9937 100644 --- a/addons/event/wizard/event_confirm.py +++ b/addons/event/wizard/event_confirm.py @@ -34,4 +34,4 @@ class event_confirm(osv.osv_memory): event_confirm() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/event_moodle/event_moodle.py b/addons/event_moodle/event_moodle.py index 59d3e530b44..8ae59ae8faa 100644 --- a/addons/event_moodle/event_moodle.py +++ b/addons/event_moodle/event_moodle.py @@ -125,7 +125,7 @@ class event_moodle(osv.osv): passwd = passwd + '+' return passwd - def check_email(self,email): + def check_email(self, email): """ check if email is correct diff --git a/addons/event_project/event_project.py b/addons/event_project/event_project.py index 8590b84c4ad..34892b56f39 100644 --- a/addons/event_project/event_project.py +++ b/addons/event_project/event_project.py @@ -55,4 +55,4 @@ class event(osv.osv): event() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/event_project/wizard/event_project_retro.py b/addons/event_project/wizard/event_project_retro.py index c7eba5e0ec1..a794749701b 100644 --- a/addons/event_project/wizard/event_project_retro.py +++ b/addons/event_project/wizard/event_project_retro.py @@ -80,4 +80,4 @@ class event_project(osv.osv_memory): event_project() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/wizard/__init__.py b/addons/hr_attendance/wizard/__init__.py index a414c9a8798..98944cc9fff 100644 --- a/addons/hr_attendance/wizard/__init__.py +++ b/addons/hr_attendance/wizard/__init__.py @@ -24,4 +24,4 @@ import hr_attendance_error import hr_attendance_byweek import hr_attendance_bymonth -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/wizard/hr_attendance_bymonth.py b/addons/hr_attendance/wizard/hr_attendance_bymonth.py index 40dca536d7d..03e1db5dc3a 100644 --- a/addons/hr_attendance/wizard/hr_attendance_bymonth.py +++ b/addons/hr_attendance/wizard/hr_attendance_bymonth.py @@ -50,4 +50,4 @@ class hr_attendance_bymonth(osv.osv_memory): hr_attendance_bymonth() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/wizard/hr_attendance_byweek.py b/addons/hr_attendance/wizard/hr_attendance_byweek.py index 139ff94cd5a..9ee69a937d1 100644 --- a/addons/hr_attendance/wizard/hr_attendance_byweek.py +++ b/addons/hr_attendance/wizard/hr_attendance_byweek.py @@ -48,4 +48,4 @@ class hr_attendance_byweek(osv.osv_memory): hr_attendance_byweek() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/wizard/hr_attendance_error.py b/addons/hr_attendance/wizard/hr_attendance_error.py index bb181268195..a3e3f63aa27 100644 --- a/addons/hr_attendance/wizard/hr_attendance_error.py +++ b/addons/hr_attendance/wizard/hr_attendance_error.py @@ -66,4 +66,4 @@ class hr_attendance_error(osv.osv_memory): hr_attendance_error() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_evaluation/hr_evaluation.py b/addons/hr_evaluation/hr_evaluation.py index 6e1983d7a11..ecca6714cbd 100644 --- a/addons/hr_evaluation/hr_evaluation.py +++ b/addons/hr_evaluation/hr_evaluation.py @@ -244,7 +244,7 @@ class hr_evaluation(osv.osv): raise osv.except_osv(_('Warning !'),_("You cannot change state, because some appraisal in waiting answer or draft state")) return True - def button_done(self,cr, uid, ids, context=None): + def button_done(self, cr, uid, ids, context=None): self.write(cr, uid, ids,{'progress': 1 * 100}, context=context) self.write(cr, uid, ids,{'state':'done', 'date_close': time.strftime('%Y-%m-%d')}, context=context) return True diff --git a/addons/hr_payroll/report/report_contribution_register.py b/addons/hr_payroll/report/report_contribution_register.py index e32e93532b5..c0285f3de50 100644 --- a/addons/hr_payroll/report/report_contribution_register.py +++ b/addons/hr_payroll/report/report_contribution_register.py @@ -72,4 +72,4 @@ class contribution_register_report(report_sxw.rml_parse): report_sxw.report_sxw('report.contribution.register.lines', 'hr.contribution.register', 'hr_payroll/report/report_contribution_register.rml', parser=contribution_register_report) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_payroll/report/report_payslip.py b/addons/hr_payroll/report/report_payslip.py index e2ef7dab974..df4c729b298 100644 --- a/addons/hr_payroll/report/report_payslip.py +++ b/addons/hr_payroll/report/report_payslip.py @@ -46,4 +46,4 @@ class payslip_report(report_sxw.rml_parse): report_sxw.report_sxw('report.payslip', 'hr.payslip', 'hr_payroll/report/report_payslip.rml', parser=payslip_report) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_payroll/report/report_payslip_details.py b/addons/hr_payroll/report/report_payslip_details.py index 1e9839eaa6f..5a110cbfdcd 100644 --- a/addons/hr_payroll/report/report_payslip_details.py +++ b/addons/hr_payroll/report/report_payslip_details.py @@ -116,4 +116,4 @@ class payslip_details_report(report_sxw.rml_parse): report_sxw.report_sxw('report.paylip.details', 'hr.payslip', 'hr_payroll/report/report_payslip_details.rml', parser=payslip_details_report) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_payroll_account/__init__.py b/addons/hr_payroll_account/__init__.py index ffe4b707ac0..ceb8531473b 100644 --- a/addons/hr_payroll_account/__init__.py +++ b/addons/hr_payroll_account/__init__.py @@ -23,4 +23,4 @@ import hr_payroll_account import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_payroll_account/wizard/__init__.py b/addons/hr_payroll_account/wizard/__init__.py index 27128f05597..ee460faefb8 100644 --- a/addons/hr_payroll_account/wizard/__init__.py +++ b/addons/hr_payroll_account/wizard/__init__.py @@ -22,4 +22,4 @@ import hr_payroll_payslips_by_employees -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py b/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py index a00ff97ef6b..f608b88fece 100644 --- a/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py +++ b/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py @@ -37,4 +37,4 @@ class hr_payslip_employees(osv.osv_memory): hr_payslip_employees() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 68855b79d7d..e4328589676 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -213,7 +213,7 @@ class hr_applicant(crm.crm_case, osv.osv): } - def onchange_job(self,cr, uid, ids, job, context=None): + def onchange_job(self, cr, uid, ids, job, context=None): result = {} if job: diff --git a/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py b/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py index dd1667aecef..0015de25aee 100644 --- a/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py +++ b/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py @@ -29,7 +29,7 @@ class hr_recruitment_partner_create(osv.osv_memory): 'close': fields.boolean('Close job request'), } - def view_init(self, cr , uid , fields_list, context=None): + def view_init(self, cr, uid, fields_list, context=None): case_obj = self.pool.get('hr.applicant') if context is None: context = {} @@ -88,4 +88,4 @@ class hr_recruitment_partner_create(osv.osv_memory): hr_recruitment_partner_create() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py b/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py index 291c16a7644..0b57082c019 100644 --- a/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py +++ b/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py @@ -26,7 +26,7 @@ class hired_employee(osv.osv_memory): _name = 'hired.employee' _description = 'Create Employee' - def case_close(self, cr, uid,ids, context=None): + def case_close(self, cr, uid, ids, context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, @@ -39,7 +39,7 @@ class hired_employee(osv.osv_memory): self.pool.get('hr.applicant').case_close(cr, uid,context.get('active_ids',[])) return {} - def case_close_with_emp(self, cr, uid,ids, context=None): + def case_close_with_emp(self, cr, uid, ids, context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py index 11b7bb771fa..74b4375da6f 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py @@ -77,7 +77,7 @@ class account_analytic_account(osv.osv): _defaults = { 'pricelist_id': lambda self, cr, uid, ctx: ctx.get('pricelist_id', False), } - def on_change_partner_id(self, cr, uid, id, partner_id, context={}): + def on_change_partner_id(self, cr, uid, id, partner_id, context=None): res = super(account_analytic_account, self).on_change_partner_id(cr, uid, id, partner_id, context) if (not res.get('value', False)) or not partner_id: return res diff --git a/addons/hr_timesheet_invoice/report/account_analytic_profit.py b/addons/hr_timesheet_invoice/report/account_analytic_profit.py index 8b6cd7f9fbd..fc44089bf9e 100644 --- a/addons/hr_timesheet_invoice/report/account_analytic_profit.py +++ b/addons/hr_timesheet_invoice/report/account_analytic_profit.py @@ -120,4 +120,4 @@ class account_analytic_profit(report_sxw.rml_parse): report_sxw.report_sxw('report.account.analytic.profit', 'account.analytic.line', 'addons/hr_timesheet_invoice/report/account_analytic_profit.rml', parser=account_analytic_profit) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py index 134bde8a872..b5b31b7b74c 100644 --- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py +++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py @@ -38,7 +38,7 @@ class account_analytic_line(osv.osv): # 'price': boolean # 'product': many2one id # } - def invoice_cost_create(self, cr, uid, ids, data={}, context=None): + def invoice_cost_create(self, cr, uid, ids, data=None, context=None): analytic_account_obj = self.pool.get('account.analytic.account') res_partner_obj = self.pool.get('res.partner') account_payment_term_obj = self.pool.get('account.payment.term') diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index f18adbadbf8..fc4133dec87 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -374,7 +374,7 @@ class hr_timesheet_sheet(osv.osv): 'department_id':fields.many2one('hr.department','Department'), } - def _default_date_from(self,cr, uid, context=None): + def _default_date_from(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) r = user.company_id and user.company_id.timesheet_range or 'month' if r=='month': @@ -385,7 +385,7 @@ class hr_timesheet_sheet(osv.osv): return time.strftime('%Y-01-01') return time.strftime('%Y-%m-%d') - def _default_date_to(self,cr, uid, context=None): + def _default_date_to(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) r = user.company_id and user.company_id.timesheet_range or 'month' if r=='month': diff --git a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py index 5a8fa2c59b3..69e38f90fc5 100644 --- a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py +++ b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py @@ -61,4 +61,4 @@ class hr_timesheet_current_open(osv.osv_memory): hr_timesheet_current_open() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/idea/idea.py b/addons/idea/idea.py index 57b7c84351c..3c9b70c1a8d 100644 --- a/addons/idea/idea.py +++ b/addons/idea/idea.py @@ -234,7 +234,7 @@ class idea_idea(osv.osv): res_id = super(idea_idea, self).create(cr, user, vals, context=context) return res_id - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): """ Create the new record in idea_idea model from existing one @param cr: A database cursor diff --git a/addons/import_base/import_framework.py b/addons/import_base/import_framework.py index 44243aa952c..c4038b6c582 100644 --- a/addons/import_base/import_framework.py +++ b/addons/import_base/import_framework.py @@ -228,7 +228,7 @@ class import_framework(Thread): return map - def _fields_mapp(self,dict_sugar, openerp_dict, table): + def _fields_mapp(self, dict_sugar, openerp_dict, table): """ call all the mapper and transform data to be compatible with import_data diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py index d6e43866bf2..af5ea6d9b62 100644 --- a/addons/import_sugarcrm/import_sugarcrm.py +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -253,7 +253,7 @@ class sugar_import(import_framework): val['datas_fname'] = Filename return val - def get_history_mapping(self): + def get_history_mapping(self): return { 'model' : 'ir.attachment', 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL, self.TABLE_EMAIL], @@ -301,7 +301,7 @@ class sugar_import(import_framework): val['email_from'] = partner_email return val - def get_crm_claim_mapping(self): + def get_crm_claim_mapping(self): return { 'model' : 'crm.claim', 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD], @@ -604,7 +604,7 @@ class sugar_import(import_framework): partner_contact_email = address.email return partner_contact_id, partner_contact_email - def import_opp(self, val): + def import_opp(self, val): partner_contact_id, partner_contact_email = self.import_opportunity_contact(val) val['partner_address_id/id'] = partner_contact_id val['email_from'] = partner_contact_email diff --git a/addons/l10n_be/__init__.py b/addons/l10n_be/__init__.py index 1b2677d295e..0aeeb2be23b 100644 --- a/addons/l10n_be/__init__.py +++ b/addons/l10n_be/__init__.py @@ -22,4 +22,4 @@ import company import wizard -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be_invoice_bba/invoice.py b/addons/l10n_be_invoice_bba/invoice.py index 997036c0cec..da2545669ad 100644 --- a/addons/l10n_be_invoice_bba/invoice.py +++ b/addons/l10n_be_invoice_bba/invoice.py @@ -35,7 +35,7 @@ account.invoice object: class account_invoice(osv.osv): _inherit = 'account.invoice' - def _get_reference_type(self, cursor, user, context=None): + def _get_reference_type(self, cursor, user, context=None): """Add BBA Structured Communication Type and change labels from 'reference' into 'communication' """ res = super(account_invoice, self)._get_reference_type(cursor, user, context=context) @@ -44,7 +44,7 @@ class account_invoice(osv.osv): #logger.notifyChannel('addons.'+self._name, netsvc.LOG_WARNING, 'reference_type = %s' %res ) return res - def check_bbacomm(self, val): + def check_bbacomm(self, val): supported_chars = '0-9+*/ ' pattern = re.compile('[^' + supported_chars + ']') if pattern.findall(val or ''): @@ -57,7 +57,7 @@ class account_invoice(osv.osv): return True return False - def _check_communication(self, cr, uid, ids): + def _check_communication(self, cr, uid, ids): for inv in self.browse(cr, uid, ids): if inv.reference_type == 'bba': return self.check_bbacomm(inv.reference) @@ -86,7 +86,7 @@ class account_invoice(osv.osv): result['value'].update(res_update) return result - def generate_bbacomm(self, cr, uid, ids, type, reference_type, algorithm, partner_id, reference): + def generate_bbacomm(self, cr, uid, ids, type, reference_type, algorithm, partner_id, reference): partner_obj = self.pool.get('res.partner') reference = reference or '' if (type == 'out_invoice'): @@ -157,7 +157,7 @@ class account_invoice(osv.osv): "\nPlease contact your OpenERP support channel.") % algorithm) return {'value': {'reference': reference}} - def create(self, cr, uid, vals, context=None): + def create(self, cr, uid, vals, context=None): if vals.has_key('reference_type'): reference_type = vals['reference_type'] if reference_type == 'bba': @@ -179,7 +179,7 @@ class account_invoice(osv.osv): '\nPlease create manually a unique BBA Structured Communication.')) return super(account_invoice, self).create(cr, uid, vals, context=context) - def write(self, cr, uid, ids, vals, context={}): + def write(self, cr, uid, ids, vals, context=None): if isinstance(ids, (int, long)): ids = [ids] for inv in self.browse(cr, uid, ids, context): diff --git a/addons/l10n_br/l10n_br.py b/addons/l10n_br/l10n_br.py index af387334cd1..f35ced7ea09 100644 --- a/addons/l10n_br/l10n_br.py +++ b/addons/l10n_br/l10n_br.py @@ -81,4 +81,4 @@ class l10n_br_account_cst(osv.osv): l10n_br_account_cst() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_ch/partner.py b/addons/l10n_ch/partner.py index 9301c564227..aba9ea7b204 100644 --- a/addons/l10n_ch/partner.py +++ b/addons/l10n_ch/partner.py @@ -30,4 +30,4 @@ class res_partner(osv.osv): } res_partner() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_ch/payment.py b/addons/l10n_ch/payment.py index aba757502b0..a681daf569d 100644 --- a/addons/l10n_ch/payment.py +++ b/addons/l10n_ch/payment.py @@ -24,7 +24,7 @@ from osv import osv class payment_order(osv.osv): _inherit = 'payment.order' - def get_wizard(self,mode): + def get_wizard(self, mode): if mode == 'dta': return 'l10n_ch', 'action_dta_create' diff --git a/addons/l10n_ch/report/report_webkit_html.py b/addons/l10n_ch/report/report_webkit_html.py index d930258f4a7..7f6bc739e6b 100644 --- a/addons/l10n_ch/report/report_webkit_html.py +++ b/addons/l10n_ch/report/report_webkit_html.py @@ -67,7 +67,7 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse): self._check(ids) return super(l10n_ch_report_webkit_html, self).set_context(objects, data, ids, report_type=report_type) - def police_absolute_path(self, inner_path) : + def police_absolute_path(self, inner_path): """Will get the ocrb police absolute path""" path = addons.get_module_resource(os.path.join('l10n_ch', 'report', inner_path)) return path diff --git a/addons/l10n_ch/wizard/create_dta.py b/addons/l10n_ch/wizard/create_dta.py index e9b0585d4c8..a94ac70afde 100644 --- a/addons/l10n_ch/wizard/create_dta.py +++ b/addons/l10n_ch/wizard/create_dta.py @@ -41,7 +41,7 @@ TRANS=[ (u'ä','a'), ] -def _u2a(text) : +def _u2a(text): """Tries to convert unicode charactere to asci equivalence""" if not text : return "" txt = "" diff --git a/addons/l10n_fr/l10n_fr.py b/addons/l10n_fr/l10n_fr.py index 573f4f7519e..8cf237d03f0 100644 --- a/addons/l10n_fr/l10n_fr.py +++ b/addons/l10n_fr/l10n_fr.py @@ -51,4 +51,4 @@ class l10n_fr_line(osv.osv): l10n_fr_line() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr/report/base_report.py b/addons/l10n_fr/report/base_report.py index 2c44b062f45..c93d5308901 100644 --- a/addons/l10n_fr/report/base_report.py +++ b/addons/l10n_fr/report/base_report.py @@ -117,4 +117,4 @@ class base_report(report_sxw.rml_parse): break self._set_variable(code, sum) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr/wizard/fr_report_bilan.py b/addons/l10n_fr/wizard/fr_report_bilan.py index cec2e513a6a..1ed2389671d 100644 --- a/addons/l10n_fr/wizard/fr_report_bilan.py +++ b/addons/l10n_fr/wizard/fr_report_bilan.py @@ -54,4 +54,4 @@ class account_bilan_report(osv.osv_memory): account_bilan_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr/wizard/fr_report_compute_resultant.py b/addons/l10n_fr/wizard/fr_report_compute_resultant.py index d90466ea6c4..b29789bdd04 100644 --- a/addons/l10n_fr/wizard/fr_report_compute_resultant.py +++ b/addons/l10n_fr/wizard/fr_report_compute_resultant.py @@ -54,4 +54,4 @@ class account_cdr_report(osv.osv_memory): account_cdr_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_lu/wizard/pdf_ext.py b/addons/l10n_lu/wizard/pdf_ext.py index 3b58fab5b68..e90cf0527d2 100644 --- a/addons/l10n_lu/wizard/pdf_ext.py +++ b/addons/l10n_lu/wizard/pdf_ext.py @@ -57,7 +57,7 @@ trailer %%EOF """ -def output_field( f ): +def output_field(f): return "\xfe\xff" + "".join( [ "\x00"+c for c in f ] ) def extract_keys(lines): diff --git a/addons/lunch/report/order.py b/addons/lunch/report/order.py index 11ca7f79dbc..b1745f7d5f5 100644 --- a/addons/lunch/report/order.py +++ b/addons/lunch/report/order.py @@ -26,14 +26,14 @@ from osv import osv class order(report_sxw.rml_parse): - def get_lines(self, user,objects): + def get_lines(self, user, objects): lines=[] for obj in objects: if user.id==obj.user_id.id: lines.append(obj) return lines - def get_total(self, user,objects): + def get_total(self, user, objects): lines=[] for obj in objects: if user.id==obj.user_id.id: diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 70b536296bf..cbd165a772d 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -134,7 +134,7 @@ class mail_thread(osv.osv): self.message_append_dict(cr, uid, [res_id], msg_dict, context=context) return res_id - def message_update(self, cr, uid, ids, msg_dict, vals={}, default_act=None, context=None): + def message_update(self, cr, uid, ids, msg_dict, vals=None, default_act=None, context=None): """Called by ``message_process`` when a new message is received for an existing thread. The default behavior is to create a new mail.message in the given thread (by calling diff --git a/addons/mail/static/scripts/openerp_mailgate.py b/addons/mail/static/scripts/openerp_mailgate.py old mode 100755 new mode 100644 diff --git a/addons/membership/report/__init__.py b/addons/membership/report/__init__.py index 05c893ae400..84dc92c63f0 100644 --- a/addons/membership/report/__init__.py +++ b/addons/membership/report/__init__.py @@ -20,4 +20,4 @@ ############################################################################## import report_membership -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/membership/report/report_membership.py b/addons/membership/report/report_membership.py index 631acab46b1..ef7b790aeca 100644 --- a/addons/membership/report/report_membership.py +++ b/addons/membership/report/report_membership.py @@ -141,4 +141,4 @@ class report_membership(osv.osv): report_membership() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/membership/wizard/__init__.py b/addons/membership/wizard/__init__.py index 7ad7cc32008..a15a0a7329f 100644 --- a/addons/membership/wizard/__init__.py +++ b/addons/membership/wizard/__init__.py @@ -20,4 +20,4 @@ ############################################################################## import membership_invoice -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 8a25af01e7b..a6f58833df0 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -271,13 +271,15 @@ class mrp_bom(osv.osv): return {'value': {'name': prod.name, 'product_uom': prod.uom_id.id}} return {} - def _bom_find(self, cr, uid, product_id, product_uom, properties=[]): + def _bom_find(self, cr, uid, product_id, product_uom, properties=None): """ Finds BoM for particular product and product uom. @param product_id: Selected product. @param product_uom: Unit of measure of a product. @param properties: List of related properties. @return: False or BoM id. """ + if properties is None: + properties = [] cr.execute('select id from mrp_bom where product_id=%s and bom_id is null order by sequence', (product_id,)) ids = map(lambda x: x[0], cr.fetchall()) max_prop = 0 @@ -292,7 +294,7 @@ class mrp_bom(osv.osv): max_prop = prop return result - def _bom_explode(self, cr, uid, bom, factor, properties=[], addthis=False, level=0, routing_id=False): + def _bom_explode(self, cr, uid, bom, factor, properties=None, addthis=False, level=0, routing_id=False): """ Finds Products and Work Centers for related BoM for manufacturing order. @param bom: BoM of particular product. @param factor: Factor of product UoM. @@ -577,7 +579,7 @@ class mrp_production(osv.osv): self.write(cr, uid, ids, {'state': 'picking_except'}) return True - def action_compute(self, cr, uid, ids, properties=[], context=None): + def action_compute(self, cr, uid, ids, properties=None, context=None): """ Computes bills of material of a product. @param properties: List containing dictionaries of properties. @return: No. of products. diff --git a/addons/mrp/procurement.py b/addons/mrp/procurement.py index 4086a401f56..6e523f7592b 100644 --- a/addons/mrp/procurement.py +++ b/addons/mrp/procurement.py @@ -33,7 +33,7 @@ class procurement_order(osv.osv): 'property_ids': fields.many2many('mrp.property', 'procurement_property_rel', 'procurement_id','property_id', 'Properties'), } - def check_produce_product(self, cr, uid, procurement, context=[]): + def check_produce_product(self, cr, uid, procurement, context=None): """ Finds the bill of material for the product from procurement order. @return: True or False """ diff --git a/addons/mrp/report/bom_structure.py b/addons/mrp/report/bom_structure.py index a5b43c19f01..458a0c19649 100644 --- a/addons/mrp/report/bom_structure.py +++ b/addons/mrp/report/bom_structure.py @@ -35,7 +35,7 @@ class bom_structure(report_sxw.rml_parse): def get_children(self, object, level=0): result = [] - def _get_rec(object,level): + def _get_rec(object, level): for l in object: res = {} res['name'] = l.name @@ -61,4 +61,4 @@ class bom_structure(report_sxw.rml_parse): report_sxw.report_sxw('report.bom.structure','mrp.bom','mrp/report/bom_structure.rml',parser=bom_structure,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index d5ddc7f0280..fdfe09f35b4 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -102,7 +102,7 @@ class StockMove(osv.osv): wf_service.trg_validate(uid, 'procurement.order', m, 'button_wait_done', cr) return processed_ids - def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None): + def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None): """ Consumed product with specific quatity from specific source location. @param product_qty: Consumed product quantity @param location_id: Source location diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index fbf307e860e..28610d89a5b 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -372,7 +372,7 @@ class mrp_production(osv.osv): pass return result - def action_compute(self, cr, uid, ids, properties=[], context=None): + def action_compute(self, cr, uid, ids, properties=None, context=None): """ Computes bills of material of a product and planned date of work order. @param properties: List containing dictionaries of properties. @return: No. of products. diff --git a/addons/plugin/plugin_handler.py b/addons/plugin/plugin_handler.py index ef990170e64..3c81edae2fa 100644 --- a/addons/plugin/plugin_handler.py +++ b/addons/plugin/plugin_handler.py @@ -132,7 +132,7 @@ class plugin_handler(osv.osv_memory): return ('res.partner', partner_id, url) # Specific to outlook rfc822 is not available so we split in arguments headerd,body,attachemnts - def push_message_outlook(self, cr, uid, model, headers,res_id=0 ,body_text=False, body_html=False, attachments=False): + def push_message_outlook(self, cr, uid, model, headers, res_id=0 , body_text=False, body_html=False, attachments=False): # ---------------------------------------- # solution 1 # construct a fake rfc822 from the separated arguement diff --git a/addons/point_of_sale/report/account_statement.py b/addons/point_of_sale/report/account_statement.py index be5d4b3a330..c1fc73a35d7 100644 --- a/addons/point_of_sale/report/account_statement.py +++ b/addons/point_of_sale/report/account_statement.py @@ -48,4 +48,4 @@ class account_statement(report_sxw.rml_parse): report_sxw.report_sxw('report.account.statement', 'account.bank.statement', 'addons/statement/report/account_statement.rml', parser=account_statement,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/all_closed_cashbox_of_the_day.py b/addons/point_of_sale/report/all_closed_cashbox_of_the_day.py index 4f342099a59..0e75e7f7ae1 100644 --- a/addons/point_of_sale/report/all_closed_cashbox_of_the_day.py +++ b/addons/point_of_sale/report/all_closed_cashbox_of_the_day.py @@ -38,13 +38,13 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): 'get_net_total_starting':self._get_net_total_starting, }) - def _get_user(self,line_ids): + def _get_user(self, line_ids): sql = "select name from res_users where id = %d"%(line_ids['create_uid']) self.cr.execute(sql) user = self.cr.fetchone() return user[0] - def _get_data(self,user): + def _get_data(self, user): data = {} sql = """ SELECT abs.journal_id,abs.id,abs.date,abs.closing_date,abs.name as statement,aj.name as journal,ap.name as period,ru.name as user,rc.name as company, abs.state,abs.balance_end_real FROM account_bank_statement as abs @@ -57,7 +57,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): data = self.cr.dictfetchall() return data - def _get_lines(self,statement): + def _get_lines(self, statement): data = {} sql = """ select absl.* from account_bank_statement_line as absl, account_bank_statement as abs where absl.statement_id = abs.id and abs.id = %d"""%(statement['id']) @@ -65,7 +65,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): data = self.cr.dictfetchall() return data - def _get_bal(self,data): + def _get_bal(self, data): res = {} sql =""" select sum(pieces*number) as bal from account_cashbox_line where starting_id = %d """%(data['id']) self.cr.execute(sql) @@ -75,7 +75,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): else: return False - def _get_sub_total(self,user,data,date): + def _get_sub_total(self, user, data, date): res={} self.cr.execute(""" select sum(absl.amount) from account_bank_statement as abs LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id @@ -90,7 +90,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): else: return False - def _get_partner(self,statement): + def _get_partner(self, statement): res = {} if statement['pos_statement_id']: sql =""" select rp.name from account_bank_statement_line as absl,res_partner as rp @@ -102,7 +102,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): else: return 0.00 - def _get_net_total_starting(self,user): + def _get_net_total_starting(self, user): lst = [] res={} total_ending_bal = 0.0 @@ -124,7 +124,7 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): lst.append(total_starting_bal) return lst - def _get_net_total(self,user): + def _get_net_total(self, user): res={} sql = """select sum(absl.amount) as net_total from account_bank_statement as abs LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id @@ -137,4 +137,4 @@ class all_closed_cashbox_of_the_day(report_sxw.rml_parse): report_sxw.report_sxw('report.all.closed.cashbox.of.the.day', 'account.bank.statement', 'addons/point_of_sale/report/all_closed_cashbox_of_the_day.rml', parser=all_closed_cashbox_of_the_day,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_details.py b/addons/point_of_sale/report/pos_details.py index d13c127165e..f8565a8776a 100644 --- a/addons/point_of_sale/report/pos_details.py +++ b/addons/point_of_sale/report/pos_details.py @@ -24,7 +24,7 @@ from report import report_sxw class pos_details(report_sxw.rml_parse): - def _get_invoice(self,inv_id): + def _get_invoice(self, inv_id): res={} if inv_id: self.cr.execute("select number from account_invoice as ac where id = %s", (inv_id,)) @@ -37,7 +37,7 @@ class pos_details(report_sxw.rml_parse): user_obj = self.pool.get('res.users') return user_obj.search(self.cr, self.uid, []) - def _pos_sales_details(self,form): + def _pos_sales_details(self, form): pos_obj = self.pool.get('pos.order') user_obj = self.pool.get('res.users') data = [] @@ -74,7 +74,7 @@ class pos_details(report_sxw.rml_parse): def _get_sales_total_2(self): return self.total - def _get_sum_invoice_2(self,form): + def _get_sum_invoice_2(self, form): pos_obj = self.pool.get('pos.order') user_obj = self.pool.get('res.users') user_ids = form['user_ids'] or self._get_all_users() diff --git a/addons/point_of_sale/report/pos_details_summary.py b/addons/point_of_sale/report/pos_details_summary.py index 2801dcf43f3..c811d6543ba 100644 --- a/addons/point_of_sale/report/pos_details_summary.py +++ b/addons/point_of_sale/report/pos_details_summary.py @@ -42,7 +42,7 @@ class pos_details_summary(report_sxw.rml_parse): 'getcompany':self.get_company }) - def get_company(self,objects): + def get_company(self, objects): comp=[obj.company_id.name for obj in objects] return '%s' % (comp[0]) @@ -136,4 +136,4 @@ report_sxw.report_sxw('report.pos.details_summary', parser=pos_details_summary, header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_lines.py b/addons/point_of_sale/report/pos_lines.py index 66b52d6ce01..6c48d9e9733 100644 --- a/addons/point_of_sale/report/pos_lines.py +++ b/addons/point_of_sale/report/pos_lines.py @@ -41,7 +41,7 @@ class pos_lines(report_sxw.rml_parse): self.total = tot return self.total - def __taxes__(self,obj): + def __taxes__(self, obj): self.cr.execute ( " Select acct.name from pos_order as po " \ " LEFT JOIN pos_order_line as pol ON po.id = pol.order_id " \ " LEFT JOIN product_taxes_rel as ptr ON pol.product_id = ptr.prod_id " \ @@ -52,4 +52,4 @@ class pos_lines(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.lines', 'pos.order', 'addons/point_of_sale/report/pos_lines.rml', parser=pos_lines,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_payment_report.py b/addons/point_of_sale/report/pos_payment_report.py index beadd2d5cb6..1fed98a4852 100644 --- a/addons/point_of_sale/report/pos_payment_report.py +++ b/addons/point_of_sale/report/pos_payment_report.py @@ -33,7 +33,7 @@ class pos_payment_report(report_sxw.rml_parse): 'pos_payment_total':self._pos_payment_total, }) - def _pos_payment(self,obj): + def _pos_payment(self, obj): data={} sql = """ select id from pos_order where id = %d"""%(obj.id) self.cr.execute(sql) @@ -56,9 +56,9 @@ class pos_payment_report(report_sxw.rml_parse): self.total += d['price_unit'] * d['qty'] return data - def _pos_payment_total(self,o): + def _pos_payment_total(self, o): return self.total report_sxw.report_sxw('report.pos.payment.report', 'pos.order', 'addons/point_of_sale/report/pos_payment_report.rml', parser=pos_payment_report,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_payment_report_user.py b/addons/point_of_sale/report/pos_payment_report_user.py index c90387e4f7a..b347c86da2a 100644 --- a/addons/point_of_sale/report/pos_payment_report_user.py +++ b/addons/point_of_sale/report/pos_payment_report_user.py @@ -33,7 +33,7 @@ class pos_payment_report_user(report_sxw.rml_parse): 'pos_payment_user_total':self.__pos_payment_user__total__, }) - def __pos_payment_user__(self,form): + def __pos_payment_user__(self, form): data={} ids = form['user_id'] sql = "select pt.name,pp.default_code as code,pol.qty,pu.name as uom,pol.discount,pol.price_unit, " \ @@ -61,4 +61,4 @@ class pos_payment_report_user(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.payment.report.user', 'pos.order', 'addons/point_of_sale/report/pos_payment_report_user.rml', parser=pos_payment_report_user,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_receipt.py b/addons/point_of_sale/report/pos_receipt.py index 721f4bc86e2..966bdd42259 100644 --- a/addons/point_of_sale/report/pos_receipt.py +++ b/addons/point_of_sale/report/pos_receipt.py @@ -74,4 +74,4 @@ class order(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.receipt', 'pos.order', 'addons/point_of_sale/report/pos_receipt.rml', parser=order, header=False) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_sales_user.py b/addons/point_of_sale/report/pos_sales_user.py index e49528441b9..f40b9f1c630 100644 --- a/addons/point_of_sale/report/pos_sales_user.py +++ b/addons/point_of_sale/report/pos_sales_user.py @@ -33,7 +33,7 @@ class pos_sales_user(report_sxw.rml_parse): }) - def _get_data(self,form): + def _get_data(self, form): dt1 = form['date_start'] + ' 00:00:00' dt2 = form['date_end'] + ' 23:59:59' data={} @@ -47,4 +47,4 @@ class pos_sales_user(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.sales.user', 'pos.order', 'addons/point_of_sale/report/pos_sales_user.rml', parser=pos_sales_user,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_sales_user_today.py b/addons/point_of_sale/report/pos_sales_user_today.py index 9696d036959..35bc61efea8 100644 --- a/addons/point_of_sale/report/pos_sales_user_today.py +++ b/addons/point_of_sale/report/pos_sales_user_today.py @@ -33,7 +33,7 @@ class pos_sales_user_today(report_sxw.rml_parse): }) - def _get_data(self,form): + def _get_data(self, form): data={} ids = form['user_id'] @@ -47,4 +47,4 @@ class pos_sales_user_today(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.sales.user.today', 'pos.order', 'addons/point_of_sale/report/pos_sales_user_today.rml', parser=pos_sales_user_today,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_users_product.py b/addons/point_of_sale/report/pos_users_product.py index 87cf306990a..032a25043e8 100644 --- a/addons/point_of_sale/report/pos_users_product.py +++ b/addons/point_of_sale/report/pos_users_product.py @@ -60,9 +60,9 @@ class pos_user_product(report_sxw.rml_parse): data = self.cr.fetchone() return data[0] - def _get_total(self,o): + def _get_total(self, o): return self.total report_sxw.report_sxw('report.pos.user.product', 'account.bank.statement', 'addons/statement/report/pos_users_product.rml', parser=pos_user_product,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/report_cash_register.py b/addons/point_of_sale/report/report_cash_register.py index c86c40bb32f..ff3823a4386 100644 --- a/addons/point_of_sale/report/report_cash_register.py +++ b/addons/point_of_sale/report/report_cash_register.py @@ -65,4 +65,4 @@ class report_cash_register(osv.osv): report_cash_register() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/company.py b/addons/procurement/company.py index d544181a6e8..23a0214f1c6 100644 --- a/addons/procurement/company.py +++ b/addons/procurement/company.py @@ -35,4 +35,4 @@ class company(osv.osv): company() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/product.py b/addons/product/product.py index 0d5fa31ac11..42f587a91a4 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -349,7 +349,7 @@ class product_template(osv.osv): res = False return res - def onchange_uom(self, cursor, user, ids, uom_id,uom_po_id): + def onchange_uom(self, cursor, user, ids, uom_id, uom_po_id): if uom_id: return {'value': {'uom_po_id': uom_id}} return {} @@ -540,7 +540,7 @@ class product_product(osv.osv): self.pool.get('product.template').unlink(cr, uid, unlink_product_tmpl_ids, context=context) return super(product_product, self).unlink(cr, uid, unlink_ids, context=context) - def onchange_uom(self, cursor, user, ids, uom_id,uom_po_id): + def onchange_uom(self, cursor, user, ids, uom_id, uom_po_id): if uom_id and uom_po_id: uom_obj=self.pool.get('product.uom') uom=uom_obj.browse(cursor,user,[uom_id])[0] diff --git a/addons/product/report/product_pricelist.py b/addons/product/report/product_pricelist.py index 7e9748c2523..f2b5a57f472 100644 --- a/addons/product/report/product_pricelist.py +++ b/addons/product/report/product_pricelist.py @@ -39,7 +39,7 @@ class product_pricelist(report_sxw.rml_parse): 'get_titles': self._get_titles, }) - def _get_titles(self,form): + def _get_titles(self, form): lst = [] vals = {} qtys = 1 @@ -51,7 +51,7 @@ class product_pricelist(report_sxw.rml_parse): lst.append(vals) return lst - def _set_quantity(self,form): + def _set_quantity(self, form): for i in range(1,6): q = 'qty%d'%i if form[q] >0 and form[q] not in self.quantity: @@ -76,7 +76,7 @@ class product_pricelist(report_sxw.rml_parse): symbol = pool.get('res.currency').read(self.cr, self.uid, [pricelist['currency_id'][0]], ['symbol'], context=self.localcontext)[0] return symbol['symbol'] or '' - def _get_categories(self, products,form): + def _get_categories(self, products, form): cat_ids=[] res=[] self.pricelist = form['price_list'] @@ -111,7 +111,7 @@ class product_pricelist(report_sxw.rml_parse): res.append({'name':cat[1],'products': products}) return res - def _get_price(self,pricelist_id, product_id,qty): + def _get_price(self, pricelist_id, product_id, qty): sale_price_digits = self.get_digits(dp='Sale Price') pool = pooler.get_pool(self.cr.dbname) price_dict = pool.get('product.pricelist').price_get(self.cr, self.uid, [pricelist_id], product_id, qty, context=self.localcontext) diff --git a/addons/product_manufacturer/product_manufacturer.py b/addons/product_manufacturer/product_manufacturer.py index 93f4a6f1a8e..1aeff8d4f78 100644 --- a/addons/product_manufacturer/product_manufacturer.py +++ b/addons/product_manufacturer/product_manufacturer.py @@ -40,4 +40,4 @@ class product_attribute(osv.osv): } product_attribute() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_visible_discount/__init__.py b/addons/product_visible_discount/__init__.py index 4abaf54aa85..b1dda0c009e 100644 --- a/addons/product_visible_discount/__init__.py +++ b/addons/product_visible_discount/__init__.py @@ -20,4 +20,4 @@ import product_visible_discount -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/project.py b/addons/project/project.py index 9966ad02ee8..bdc5338b802 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -265,7 +265,7 @@ class project(osv.osv): task_obj.duplicate_task(cr, uid, map_task_id, context=context) return True - def copy(self, cr, uid, id, default={}, context=None): + def copy(self, cr, uid, id, default=None, context=None): if context is None: context = {} @@ -545,12 +545,12 @@ class task(osv.osv): return res - def onchange_remaining(self, cr, uid, ids, remaining=0.0, planned = 0.0): + def onchange_remaining(self, cr, uid, ids, remaining=0.0, planned=0.0): if remaining and not planned: return {'value':{'planned_hours': remaining}} return {} - def onchange_planned(self, cr, uid, ids, planned = 0.0, effective = 0.0): + def onchange_planned(self, cr, uid, ids, planned=0.0, effective=0.0): return {'value':{'remaining_hours': planned - effective}} def onchange_project(self, cr, uid, id, project_id): @@ -581,7 +581,9 @@ class task(osv.osv): #FIXME why there is already the copy and the old one self.write(cr, uid, new, {'parent_ids':[(6,0,set(parent_ids))], 'child_ids':[(6,0, set(child_ids))]}) - def copy_data(self, cr, uid, id, default={}, context=None): + def copy_data(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} default = default or {} default.update({'work_ids':[], 'date_start': False, 'date_end': False, 'date_deadline': False}) if not default.get('remaining_hours', False): @@ -810,7 +812,7 @@ class task(osv.osv): } return res - def do_close(self, cr, uid, ids, context={}): + def do_close(self, cr, uid, ids, context=None): """ Close Task """ @@ -868,7 +870,7 @@ class task(osv.osv): self.write(cr, uid, [task.id], {'state': 'open'}, context=context) return True - def do_cancel(self, cr, uid, ids, context={}): + def do_cancel(self, cr, uid, ids, context=None): request = self.pool.get('res.request') tasks = self.browse(cr, uid, ids, context=context) self._check_child_task(cr, uid, ids, context=context) @@ -889,7 +891,7 @@ class task(osv.osv): self.write(cr, uid, [task.id], {'state': 'cancelled', 'remaining_hours':0.0}, context=context) return True - def do_open(self, cr, uid, ids, context={}): + def do_open(self, cr, uid, ids, context=None): if not isinstance(ids,list): ids = [ids] tasks= self.browse(cr, uid, ids, context=context) for t in tasks: @@ -901,7 +903,7 @@ class task(osv.osv): self.log(cr, uid, t.id, message) return True - def do_draft(self, cr, uid, ids, context={}): + def do_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'draft'}, context=context) return True @@ -915,10 +917,12 @@ class task(osv.osv): return new_attachment_ids - def do_delegate(self, cr, uid, ids, delegate_data={}, context=None): + def do_delegate(self, cr, uid, ids, delegate_data=None, context=None): """ Delegate Task to another users. """ + if delegate_data is None: + delegate_data = {} assert delegate_data['user_id'], _("Delegated User should be specified") delegated_tasks = {} for task in self.browse(cr, uid, ids, context=context): @@ -950,7 +954,7 @@ class task(osv.osv): delegated_tasks[task.id] = delegated_task_id return delegated_tasks - def do_pending(self, cr, uid, ids, context={}): + def do_pending(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'pending'}, context=context) for (id, name) in self.name_get(cr, uid, ids): message = _("The task '%s' is pending.") % name diff --git a/addons/project/wizard/project_task_reevaluate.py b/addons/project/wizard/project_task_reevaluate.py index 382c9d64361..b00c531717f 100644 --- a/addons/project/wizard/project_task_reevaluate.py +++ b/addons/project/wizard/project_task_reevaluate.py @@ -26,7 +26,7 @@ from tools.translate import _ class project_task_reevaluate(osv.osv_memory): _name = 'project.task.reevaluate' - def _get_remaining(self,cr, uid, context=None): + def _get_remaining(self, cr, uid, context=None): if context is None: context = {} active_id = context.get('active_id', False) diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py index bec70779551..e11ce1339de 100644 --- a/addons/project_gtd/project_gtd.py +++ b/addons/project_gtd/project_gtd.py @@ -67,7 +67,7 @@ class project_task(osv.osv): default['context_id'] = False return super(project_task,self).copy_data(cr, uid, id, default, context) - def _get_context(self,cr, uid, context=None): + def _get_context(self, cr, uid, context=None): ids = self.pool.get('project.gtd.context').search(cr, uid, [], context=context) return ids and ids[0] or False diff --git a/addons/project_gtd/wizard/project_gtd_empty.py b/addons/project_gtd/wizard/project_gtd_empty.py index 373c8425a8c..268dfd26917 100644 --- a/addons/project_gtd/wizard/project_gtd_empty.py +++ b/addons/project_gtd/wizard/project_gtd_empty.py @@ -30,7 +30,7 @@ class project_timebox_empty(osv.osv_memory): 'name': fields.char('Name', size=32) } - def view_init(self, cr , uid , fields_list, context=None): + def view_init(self, cr, uid, fields_list, context=None): if context is None: context = {} self._empty(cr, uid, context=context) diff --git a/addons/project_mailgate/project_mailgate.py b/addons/project_mailgate/project_mailgate.py index 9715a32c151..1243d8f759d 100644 --- a/addons/project_mailgate/project_mailgate.py +++ b/addons/project_mailgate/project_mailgate.py @@ -47,7 +47,9 @@ class project_tasks(osv.osv): self.write(cr, uid, [res_id], data, context) return res_id - def message_update(self, cr, uid, ids, msg, data={}, default_act='pending'): + def message_update(self, cr, uid, ids, msg, data=None, default_act='pending'): + if data is None: + data = {} data.update({ 'description': msg['body_text'], }) diff --git a/addons/project_mrp/project_procurement.py b/addons/project_mrp/project_procurement.py index 7d3045aede0..ab545adfe48 100644 --- a/addons/project_mrp/project_procurement.py +++ b/addons/project_mrp/project_procurement.py @@ -40,7 +40,7 @@ class procurement_order(osv.osv): return all(proc.product_id.type != 'service' or (proc.task_id and proc.task_id.state in ('done', 'cancelled')) \ for proc in self.browse(cr, uid, ids, context=context)) - def check_produce_service(self, cr, uid, procurement, context=None): + def check_produce_service(self, cr, uid, procurement, context=None): return True def _convert_qty_company_hours(self, cr, uid, procurement, context=None): diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py index db7066505e1..c38b6b6258e 100644 --- a/addons/project_timesheet/project_timesheet.py +++ b/addons/project_timesheet/project_timesheet.py @@ -197,7 +197,7 @@ class task(osv.osv): return super(task,self).unlink(cr, uid, ids, *args, **kwargs) - def write(self, cr, uid, ids,vals,context=None): + def write(self, cr, uid, ids, vals, context=None): if context is None: context = {} if vals.get('project_id',False) or vals.get('name',False): diff --git a/addons/project_timesheet/report/task_report.py b/addons/project_timesheet/report/task_report.py index 3c223ab6b07..a181c4a12d2 100644 --- a/addons/project_timesheet/report/task_report.py +++ b/addons/project_timesheet/report/task_report.py @@ -29,7 +29,7 @@ class report_timesheet_task_user(osv.osv): _auto = False _order = "name" - def _get_task_hours(self, cr, uid, ids, name,args,context): + def _get_task_hours(self, cr, uid, ids, name, args, context): result = {} for record in self.browse(cr, uid, ids,context): last_date = datetime.strptime(record.name, '%Y-%m-%d') + relativedelta(months=1) - relativedelta(days=1) @@ -42,7 +42,7 @@ class report_timesheet_task_user(osv.osv): result[record.id] = total return result - def get_hrs_timesheet(self, cr, uid, ids, name,args,context): + def get_hrs_timesheet(self, cr, uid, ids, name, args, context): result = {} sum = 0.0 for record in self.browse(cr, uid, ids, context): diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 3d909c1085e..cb485ebc26c 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -395,7 +395,7 @@ class purchase_order(osv.osv): res = inv_id return res - def has_stockable_product(self,cr, uid, ids, *args): + def has_stockable_product(self, cr, uid, ids, *args): for order in self.browse(cr, uid, ids): for order_line in order.order_line: if order_line.product_id and order_line.product_id.product_tmpl_id.type in ('product', 'consu'): @@ -498,7 +498,7 @@ class purchase_order(osv.osv): wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr) return [picking_id] - def action_picking_create(self,cr, uid, ids, context=None): + def action_picking_create(self, cr, uid, ids, context=None): picking_ids = [] for order in self.browse(cr, uid, ids): picking_ids.extend(self._create_pickings(cr, uid, order, order.order_line, None, context=context)) diff --git a/addons/purchase/wizard/purchase_order_group.py b/addons/purchase/wizard/purchase_order_group.py index 427c9c165fc..e5c0eb81bb4 100644 --- a/addons/purchase/wizard/purchase_order_group.py +++ b/addons/purchase/wizard/purchase_order_group.py @@ -88,4 +88,4 @@ class purchase_order_group(osv.osv_memory): purchase_order_group() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index c43bd524090..a753f5d7e1a 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -183,7 +183,7 @@ class purchase_requisition_line(osv.osv): 'company_id': fields.related('requisition_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True), } - def onchange_product_id(self, cr, uid, ids, product_id,product_uom_id, context=None): + def onchange_product_id(self, cr, uid, ids, product_id, product_uom_id, context=None): """ Changes UoM and name if product_id changes. @param name: Name of the field @param product_id: Changed product_id diff --git a/addons/report_webkit/ir_report.py b/addons/report_webkit/ir_report.py index d2709ea6fc2..68e129d021d 100644 --- a/addons/report_webkit/ir_report.py +++ b/addons/report_webkit/ir_report.py @@ -35,7 +35,7 @@ from webkit_report import WebKitParser from report.report_sxw import rml_parse def register_report(name, model, tmpl_path, parser=rml_parse): - "Register the report into the services" + """Register the report into the services""" name = 'report.%s' % name if netsvc.Service._services.get(name, False): service = netsvc.Service._services[name] diff --git a/addons/report_webkit/report_helper.py b/addons/report_webkit/report_helper.py index 12651f308dc..8d0a27998b0 100644 --- a/addons/report_webkit/report_helper.py +++ b/addons/report_webkit/report_helper.py @@ -75,7 +75,7 @@ class WebKitHelper(object): head = header_obj.browse(self.cursor, self.uid, header_img_id) return (head.img, head.type) - def embed_logo_by_name(self, name, width=0, height=0) : + def embed_logo_by_name(self, name, width=0, height=0): """Return HTML embedded logo by name""" img, type = self.get_logo_by_name(name) return self.embed_image(type, img, width, height) diff --git a/addons/resource/faces/task.py b/addons/resource/faces/task.py index f5240112277..53360fa047b 100644 --- a/addons/resource/faces/task.py +++ b/addons/resource/faces/task.py @@ -567,7 +567,8 @@ class _ValueWrapper(object): return result #@-node:_cmp #@+node:__getattr__ - def __getattr__(self, name): return getattr(self._value, name) + def __getattr__(self, name): + return getattr(self._value, name) #@-node:__getattr__ #@+node:__getitem__ def __getitem__(self, slice): diff --git a/addons/resource/resource.py b/addons/resource/resource.py index fb3d8c0980e..7a9ca30c68b 100644 --- a/addons/resource/resource.py +++ b/addons/resource/resource.py @@ -438,7 +438,7 @@ class resource_calendar_leaves(osv.osv): (check_dates, 'Error! leave start-date must be lower then leave end-date.', ['date_from', 'date_to']) ] - def onchange_resource(self,cr, uid, ids, resource, context=None): + def onchange_resource(self, cr, uid, ids, resource, context=None): result = {} if resource: resource_pool = self.pool.get('resource.resource') diff --git a/addons/sale/edi/sale_order.py b/addons/sale/edi/sale_order.py index d40d0b613ed..327d7602c4f 100644 --- a/addons/sale/edi/sale_order.py +++ b/addons/sale/edi/sale_order.py @@ -219,4 +219,4 @@ class sale_order_line(osv.osv, EDIMixin): edi_doc_list.append(edi_doc) return edi_doc_list -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/report/__init__.py b/addons/sale/report/__init__.py index 0248595f4da..6986639d942 100644 --- a/addons/sale/report/__init__.py +++ b/addons/sale/report/__init__.py @@ -22,4 +22,4 @@ import sale_order import sale_report -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/wizard/__init__.py b/addons/sale/wizard/__init__.py index 6cf076164d8..bfc8679de16 100644 --- a/addons/sale/wizard/__init__.py +++ b/addons/sale/wizard/__init__.py @@ -23,4 +23,4 @@ import sale_make_invoice import sale_line_invoice import sale_make_invoice_advance -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/wizard/sale_make_invoice.py b/addons/sale/wizard/sale_make_invoice.py index 5265afb9bff..b4b3772a91a 100644 --- a/addons/sale/wizard/sale_make_invoice.py +++ b/addons/sale/wizard/sale_make_invoice.py @@ -68,4 +68,4 @@ class sale_make_invoice(osv.osv_memory): sale_make_invoice() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/__init__.py b/addons/sale_crm/__init__.py index f5db3f4333b..ac44586e7db 100644 --- a/addons/sale_crm/__init__.py +++ b/addons/sale_crm/__init__.py @@ -22,4 +22,4 @@ import wizard import sale_crm -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_layout/sale_layout.py b/addons/sale_layout/sale_layout.py index 15531e76e1d..f369cc0ef6c 100644 --- a/addons/sale_layout/sale_layout.py +++ b/addons/sale_layout/sale_layout.py @@ -53,7 +53,7 @@ class sale_order_line(osv.osv): seq += 1 return invoice_line_ids - def onchange_sale_order_line_view(self, cr, uid, id, type, context={}, *args): + def onchange_sale_order_line_view(self, cr, uid, id, type, context=None, *args): temp = {} temp['value'] = {} if (not type): diff --git a/addons/sale_order_dates/sale_order_dates.py b/addons/sale_order_dates/sale_order_dates.py index ceb6d48755c..1b069cb2bed 100644 --- a/addons/sale_order_dates/sale_order_dates.py +++ b/addons/sale_order_dates/sale_order_dates.py @@ -61,4 +61,4 @@ class sale_order_dates(osv.osv): sale_order_dates() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/report/lot_overview.py b/addons/stock/report/lot_overview.py index 89974fa122b..bf2fd32e32c 100644 --- a/addons/stock/report/lot_overview.py +++ b/addons/stock/report/lot_overview.py @@ -34,7 +34,7 @@ class lot_overview(report_sxw.rml_parse): 'grand_total_price':self._grand_total, }) - def process(self,location_id): + def process(self, location_id): location_obj = pooler.get_pool(self.cr.dbname).get('stock.location') data = location_obj._product_get_report(self.cr,self.uid, [location_id]) diff --git a/addons/stock/report/lot_overview_all.py b/addons/stock/report/lot_overview_all.py index 0b4edcaecf4..552949ec4b2 100644 --- a/addons/stock/report/lot_overview_all.py +++ b/addons/stock/report/lot_overview_all.py @@ -34,7 +34,7 @@ class lot_overview_all(report_sxw.rml_parse): 'grand_total_price':self._grand_total, }) - def process(self,location_id): + def process(self, location_id): location_obj = pooler.get_pool(self.cr.dbname).get('stock.location') data = location_obj._product_get_all_report(self.cr,self.uid, [location_id]) data['location_name'] = location_obj.read(self.cr, self.uid, [location_id],['complete_name'])[0]['complete_name'] diff --git a/addons/stock/report/stock_inventory_move_report.py b/addons/stock/report/stock_inventory_move_report.py index e8c0d44bcc1..762373f1250 100644 --- a/addons/stock/report/stock_inventory_move_report.py +++ b/addons/stock/report/stock_inventory_move_report.py @@ -30,7 +30,7 @@ class stock_inventory_move(report_sxw.rml_parse): 'qty_total':self._qty_total }) - def _qty_total(self,objects): + def _qty_total(self, objects): total = 0.0 uom = objects[0].product_uom.name for obj in objects: diff --git a/addons/stock_invoice_directly/wizard/stock_invoice.py b/addons/stock_invoice_directly/wizard/stock_invoice.py index 3725d9b6d7f..4bb0ab41d88 100644 --- a/addons/stock_invoice_directly/wizard/stock_invoice.py +++ b/addons/stock_invoice_directly/wizard/stock_invoice.py @@ -47,4 +47,4 @@ class invoice_directly(osv.osv_memory): invoice_directly() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock_location/procurement_pull.py b/addons/stock_location/procurement_pull.py index 0846fe067eb..93531596688 100644 --- a/addons/stock_location/procurement_pull.py +++ b/addons/stock_location/procurement_pull.py @@ -45,7 +45,7 @@ class procurement_order(osv.osv): return (line.type_proc=='move') and (line.location_src_id) return False - def action_move_create(self, cr, uid, ids,context=None): + def action_move_create(self, cr, uid, ids, context=None): proc_obj = self.pool.get('procurement.order') move_obj = self.pool.get('stock.move') picking_obj=self.pool.get('stock.picking') diff --git a/addons/stock_planning/stock_planning.py b/addons/stock_planning/stock_planning.py index d104d57c62b..05a8cb50486 100644 --- a/addons/stock_planning/stock_planning.py +++ b/addons/stock_planning/stock_planning.py @@ -406,7 +406,7 @@ class stock_planning(osv.osv): res[val.id] = 'Future' return res - def _get_op(self, cr, uid, ids, field_names, arg, context=None): # op = OrderPoint + def _get_op(self, cr, uid, ids, field_names, arg, context=None): res = {} for val in self.browse(cr, uid, ids, context=context): res[val.id]={} diff --git a/addons/stock_planning/wizard/stock_planning_createlines.py b/addons/stock_planning/wizard/stock_planning_createlines.py index a6e12ad4bc7..24b6fd4a8ab 100644 --- a/addons/stock_planning/wizard/stock_planning_createlines.py +++ b/addons/stock_planning/wizard/stock_planning_createlines.py @@ -49,7 +49,7 @@ class stock_planning_createlines(osv.osv_memory): 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.planning', context=c), } - def create_planning(self,cr, uid, ids, context=None): + def create_planning(self, cr, uid, ids, context=None): if context is None: context = {} product_obj = self.pool.get('product.product') diff --git a/addons/survey/survey.py b/addons/survey/survey.py index 0101cef17b8..7d1d9801ada 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -514,7 +514,7 @@ class survey_question_column_heading(osv.osv): _description = 'Survey Question Column Heading' _rec_name = 'title' - def _get_in_visible_rating_weight(self,cr, uid, context=None): + def _get_in_visible_rating_weight(self, cr, uid, context=None): if context is None: context = {} if context.get('in_visible_rating_weight', False): @@ -567,7 +567,7 @@ class survey_answer(osv.osv): } return val - def _get_in_visible_answer_type(self,cr, uid, context=None): + def _get_in_visible_answer_type(self, cr, uid, context=None): if context is None: context = {} return context.get('in_visible_answer_type', False) diff --git a/addons/survey/wizard/__init__.py b/addons/survey/wizard/__init__.py index aa1270da751..0ea0e5cd424 100644 --- a/addons/survey/wizard/__init__.py +++ b/addons/survey/wizard/__init__.py @@ -27,4 +27,4 @@ import survey_selection import survey_answer import survey_print -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py index 86380e98037..ec40cc9b8d2 100644 --- a/addons/survey/wizard/survey_answer.py +++ b/addons/survey/wizard/survey_answer.py @@ -997,7 +997,7 @@ class survey_question_wiz(osv.osv_memory): return survey_question_wiz_id - def action_new_question(self,cr, uid, ids, context=None): + def action_new_question(self, cr, uid, ids, context=None): """ New survey.Question form. """ @@ -1039,7 +1039,7 @@ class survey_question_wiz(osv.osv_memory): 'context': context } - def action_edit_page(self,cr, uid, ids, context=None): + def action_edit_page(self, cr, uid, ids, context=None): """ Edit survey.page. """ @@ -1061,7 +1061,7 @@ class survey_question_wiz(osv.osv_memory): 'context': context } - def action_delete_page(self,cr, uid, ids, context=None): + def action_delete_page(self, cr, uid, ids, context=None): """ Delete survey.page. """ @@ -1087,7 +1087,7 @@ class survey_question_wiz(osv.osv_memory): 'context': context } - def action_edit_question(self,cr, uid, ids, context=None): + def action_edit_question(self, cr, uid, ids, context=None): """ Edit survey.question. """ @@ -1109,7 +1109,7 @@ class survey_question_wiz(osv.osv_memory): 'context': context } - def action_delete_question(self,cr, uid, ids, context=None): + def action_delete_question(self, cr, uid, ids, context=None): """ Delete survey.question. """ diff --git a/addons/wiki/web/widgets/rss/feedparser.py b/addons/wiki/web/widgets/rss/feedparser.py old mode 100755 new mode 100644 index 885050d49f8..ad1265a7043 --- a/addons/wiki/web/widgets/rss/feedparser.py +++ b/addons/wiki/web/widgets/rss/feedparser.py @@ -2446,8 +2446,10 @@ def _stripDoctype(data): data = doctype_pattern.sub('', data) return version, data -def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=[]): +def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=None): '''Parse a feed from a URL, file, stream, or string''' + if handlers is None: + handlers = [] result = FeedParserDict() result['feed'] = FeedParserDict() result['entries'] = [] diff --git a/addons/wiki/web/widgets/wikimarkup/__init__.py b/addons/wiki/web/widgets/wikimarkup/__init__.py index f5fe67fada1..d62b7ae42bb 100644 --- a/addons/wiki/web/widgets/wikimarkup/__init__.py +++ b/addons/wiki/web/widgets/wikimarkup/__init__.py @@ -489,7 +489,7 @@ class BaseParser(object): return text.encode("utf-8") return text - def strip(self, text, stripcomments=False, dontstrip=[]): + def strip(self, text, stripcomments=False, dontstrip=None): render = True commentState = {} @@ -2087,7 +2087,9 @@ mTagHooks = {} # quote from cgi import escape -def hook_quote(env, body, attributes={}): +def hook_quote(env, body, attributes=None): + if attributes is None: + attributes = {} text = [u'
'] if 'cite' in attributes: text.append(u"%s wrote:\n" % escape(attributes['cite'])) From c2e3dca73fcee2215c5f58d4c5d135b3d86b44c2 Mon Sep 17 00:00:00 2001 From: "Dmitrijs Ledkovs (credativ)" Date: Wed, 21 Mar 2012 10:47:40 +0000 Subject: [PATCH 007/726] [FIX] corrected unreconciled domain on Paybles & Receivables window action lp bug: https://launchpad.net/bugs/961051 fixed bzr revid: dmitrijs.ledkovs@credativ.co.uk-20120321104740-6x0ehabi3pbz2i5j --- addons/account/account_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 3d782c2b4c4..8e123bb5c33 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -2042,7 +2042,7 @@ src_model="account.journal"/> Date: Tue, 27 Mar 2012 16:49:14 +0530 Subject: [PATCH 008/726] [FIX] stock : Fixes the sorce location problem lp bug: https://launchpad.net/bugs/963750 fixed bzr revid: amb@tinyerp.com-20120327111914-mns594vtmtcr1fu7 --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index d26ca8f0da3..0e9fcfb3f50 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2355,7 +2355,7 @@ class stock_move(osv.osv): 'prodlot_id': move.prodlot_id.id, } if move.location_id.usage <> 'internal': - default_val.update({'location_id': move.location_dest_id.id}) + default_val.update({'location_id': move.location_id.id}) new_move = self.copy(cr, uid, move.id, default_val) res += [new_move] From 5833025216e6515413cc7c4e92a4f9fb4b261e60 Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Fri, 6 Apr 2012 15:04:08 +0200 Subject: [PATCH 009/726] [REF] Move stock view selection to a distinct method bzr revid: ls@numerigraphe.fr-20120406130408-hcsfinc4dutfzq0f --- addons/stock/stock.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 885f7cd2077..998386162ea 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1319,6 +1319,22 @@ class stock_picking(osv.osv): res[pick.id] = {'delivered_picking': delivered_pack.id or False} return res + + # views associated to each picking type + _VIEW_LIST = { + 'out': 'view_picking_out_form', + 'in': 'view_picking_in_form', + 'internal': 'view_picking_form', + } + def _get_view_id(self, cr, uid, type): + """Get the view id suiting the given type + + @param type: the picking type as a string + @return: view i, or False if no view found + """ + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, + 'stock', self._VIEW_LIST.get(type, 'view_picking_form')) + return res and res[1] or False def log_picking(self, cr, uid, ids, context=None): """ This function will create log messages for picking. @@ -1329,7 +1345,6 @@ class stock_picking(osv.osv): """ if context is None: context = {} - data_obj = self.pool.get('ir.model.data') for pick in self.browse(cr, uid, ids, context=context): msg='' if pick.auto_picking: @@ -1339,11 +1354,6 @@ class stock_picking(osv.osv): 'in':_('Reception'), 'internal': _('Internal picking'), } - view_list = { - 'out': 'view_picking_out_form', - 'in': 'view_picking_in_form', - 'internal': 'view_picking_form', - } message = type_list.get(pick.type, _('Document')) + " '" + (pick.name or '?') + "' " if pick.min_date: msg= _(' for the ')+ datetime.strptime(pick.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y') @@ -1355,8 +1365,7 @@ class stock_picking(osv.osv): 'auto': _('is waiting.'), 'draft': _('is in draft state.'), } - res = data_obj.get_object_reference(cr, uid, 'stock', view_list.get(pick.type, 'view_picking_form')) - context.update({'view_id': res and res[1] or False}) + context['view_id'] = self._get_view_id(cr, uid, pick.type) message += state_list[pick.state] self.log(cr, uid, pick.id, message, context=context) return True From ff392e2b4159767efcb04fefbb15eea1e88e22ee Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 6 Apr 2012 18:35:45 +0530 Subject: [PATCH 010/726] [FIX] users_idap: fixed issue of admin password bzr revid: tpa@tinyerp.com-20120406130545-nzv1bezrwl132be9 --- addons/users_ldap/users_ldap_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/users_ldap/users_ldap_view.xml b/addons/users_ldap/users_ldap_view.xml index caece7efe8f..c4e126fb3b1 100644 --- a/addons/users_ldap/users_ldap_view.xml +++ b/addons/users_ldap/users_ldap_view.xml @@ -7,13 +7,13 @@ form - +
- + From 041294a4d1d692fd3db4c819e17a4329df54d34f Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Sat, 7 Apr 2012 12:47:01 +0530 Subject: [PATCH 011/726] [FIX] stock : Fixes the access rigths problem lp bug: https://launchpad.net/bugs/971407 fixed bzr revid: amp@tinyerp.com-20120407071701-zimr1dfiq4nfyh7c --- addons/stock/security/ir.model.access.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv index a391f117393..327ccb6ff2f 100644 --- a/addons/stock/security/ir.model.access.csv +++ b/addons/stock/security/ir.model.access.csv @@ -17,7 +17,7 @@ access_stock_production_lot_manager,stock.production.lot manager,model_stock_pro access_stock_production_lot_user,stock.production.lot user,model_stock_production_lot,stock.group_stock_user,1,1,1,1 access_stock_production_lot_revision,stock.production.lot.revision,model_stock_production_lot_revision,stock.group_stock_user,1,1,1,1 access_stock_move_manager,stock.move manager,model_stock_move,stock.group_stock_manager,1,1,0,0 -access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,0,0,0 +access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,1,0,0 access_stock_inventory_user,stock.inventory user,model_stock_inventory,stock.group_stock_user,1,1,1,1 access_stock_inventory_manager,stock.inventory manager,model_stock_inventory,stock.group_stock_manager,1,0,0,0 access_stock_inventory_line_user,stock.inventory.line user,model_stock_inventory_line,stock.group_stock_user,1,1,1,1 @@ -31,8 +31,8 @@ access_stock_report_tracklots,stock.report.tracklots,model_stock_report_tracklot access_report_stock_move_user,report.stock.move user,model_report_stock_move,stock.group_stock_user,1,0,0,0 access_report_stock_move_manager,report.stock.move manager,model_report_stock_move,stock.group_stock_manager,1,1,1,1 access_report_stock_inventory_user,report.stock.inventory user,model_report_stock_inventory,stock.group_stock_user,1,1,1,1 -access_product_product_stock_user,product_product_stock_user,product.model_product_product,stock.group_stock_user,1,0,0,0 -access_product_template_stock_user,product.template stock user,product.model_product_template,stock.group_stock_user,1,0,0,0 +access_product_product_stock_user,product_product_stock_user,product.model_product_product,stock.group_stock_user,1,1,0,0 +access_product_template_stock_user,product.template stock user,product.model_product_template,stock.group_stock_user,1,1,0,0 access_account_invoice_user,account.invoice stock user,account.model_account_invoice,stock.group_stock_user,1,1,1,0 access_account_invoice_line_user,account.invoice.line stock user,account.model_account_invoice_line,stock.group_stock_user,1,1,1,0 access_account_invoice_tax_user,account.invoice.tax stock user,account.model_account_invoice_tax,stock.group_stock_user,1,1,1,0 From 1d2578c9c4c2ea0c7188ab04b61fbca11ab9eaf3 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Apr 2012 15:24:58 +0530 Subject: [PATCH 012/726] [FIX] audittrail: set the proper resource name. bzr revid: tpa@tinyerp.com-20120412095458-lr6ktlh3sh15o0th --- addons/audittrail/audittrail.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 78a180e8d4d..9b3f5e4b6fb 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -434,6 +434,7 @@ class audittrail_objects_proxy(object_proxy): on specific fields only. :return: True """ + resource_pool = pool.get(model.model) # loop on all the given ids for res_id in res_ids: # compare old and new values and get audittrail log lines accordingly @@ -441,11 +442,13 @@ class audittrail_objects_proxy(object_proxy): # if at least one modification has been found for model_id, resource_id in lines: + res_name = resource_pool.browse(cr, uid, resource_id).name vals = { 'method': method, 'object_id': model_id, 'user_id': uid, 'res_id': resource_id, + 'name': res_name or '', } if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): # the resource was not existing so we are forcing the method to 'create' From 1fcea0f2567f0360aa1c0a9baf34f90c4987337b Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Apr 2012 17:14:01 +0530 Subject: [PATCH 013/726] [IMP] audittrail: improved code bzr revid: tpa@tinyerp.com-20120412114401-e5sfeq24w69ucn83 --- addons/audittrail/audittrail.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 9b3f5e4b6fb..da7a3beaeef 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -442,13 +442,14 @@ class audittrail_objects_proxy(object_proxy): # if at least one modification has been found for model_id, resource_id in lines: - res_name = resource_pool.browse(cr, uid, resource_id).name + res_name = resource_pool.browse(cr, uid, resource_id) + name = 'name' in res_name._columns.keys() and res_name.name or '' vals = { 'method': method, 'object_id': model_id, 'user_id': uid, 'res_id': resource_id, - 'name': res_name or '', + 'name': name, } if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): # the resource was not existing so we are forcing the method to 'create' From 41d750c1d4a3ffe44315d6e9132f4bfc647a1f48 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 16 Apr 2012 10:47:14 +0200 Subject: [PATCH 014/726] [IMP] Performance improvement : if location_id already has the right value, we don't write it ! bzr revid: alexis@via.ecp.fr-20120416084714-otfuezu6tjy533nt --- addons/mrp/mrp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 9ff3a648af9..90d43b8bfc3 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -660,7 +660,7 @@ class mrp_production(osv.osv): for (production_id,name) in self.name_get(cr, uid, ids): production = self.browse(cr, uid, production_id) - if production.move_prod_id: + if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id: move_obj.write(cr, uid, [production.move_prod_id.id], {'location_id': production.location_dest_id.id}) self.action_ready_send_note(cr, uid, [production_id], context) From ca3de27dde7fe787b21877fcaff6167c156610f8 Mon Sep 17 00:00:00 2001 From: "Amit Bhavsar (Open ERP)" Date: Tue, 24 Apr 2012 11:13:59 +0530 Subject: [PATCH 015/726] [FIX]account_patment : Fixes the IntegrityError Problem lp bug: https://launchpad.net/bugs/986088 fixed bzr revid: amb@tinyerp.com-20120424054359-l0pa8rij04x63k42 --- addons/account_payment/wizard/account_payment_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py index 613b049a412..d62edc4e843 100644 --- a/addons/account_payment/wizard/account_payment_order.py +++ b/addons/account_payment/wizard/account_payment_order.py @@ -87,7 +87,7 @@ class payment_order_create(osv.osv_memory): 'partner_id': line.partner_id and line.partner_id.id or False, 'communication': line.ref or '/', 'date': date_to_pay, - 'currency': line.invoice and line.invoice.currency_id.id or False, + 'currency': line.invoice and line.invoice.currency_id.id or line.company_id.currency_id.id, }, context=context) return {'type': 'ir.actions.act_window_close'} @@ -119,4 +119,4 @@ class payment_order_create(osv.osv_memory): payment_order_create() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From db83bc2b68bb246543239725c5d57b4c873b2cde Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Tue, 24 Apr 2012 12:32:39 +0530 Subject: [PATCH 016/726] [FIX] sale,purchase : Remove the defualt uom_id from sale order line and purchase order line lp bug: https://launchpad.net/bugs/958897 fixed bzr revid: amp@tinyerp.com-20120424070239-tm531qp5js7uhzfc --- addons/purchase/purchase.py | 9 --------- addons/sale/sale.py | 9 --------- 2 files changed, 18 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 687221f371b..57f96c5cfa5 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -706,14 +706,6 @@ class purchase_order_line(osv.osv): res[line.id] = cur_obj.round(cr, uid, cur, taxes['total']) return res - def _get_uom_id(self, cr, uid, context=None): - try: - proxy = self.pool.get('ir.model.data') - result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit') - return result[1] - except Exception, ex: - return False - _columns = { 'name': fields.char('Description', size=256, required=True), 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM'), required=True), @@ -741,7 +733,6 @@ class purchase_order_line(osv.osv): } _defaults = { - 'product_uom' : _get_uom_id, 'product_qty': lambda *a: 1.0, 'state': lambda *args: 'draft', 'invoiced': lambda *a: 0, diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 9caaa86878c..f4f6b6a22eb 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -990,14 +990,6 @@ class sale_order_line(osv.osv): res[line.id] = 1 return res - def _get_uom_id(self, cr, uid, *args): - try: - proxy = self.pool.get('ir.model.data') - result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit') - return result[1] - except Exception, ex: - return False - _name = 'sale.order.line' _description = 'Sales Order Line' _columns = { @@ -1038,7 +1030,6 @@ class sale_order_line(osv.osv): } _order = 'sequence, id' _defaults = { - 'product_uom' : _get_uom_id, 'discount': 0.0, 'delay': 0.0, 'product_uom_qty': 1, From 9e68ccd264b1ac04606f0abe0e58ffb04fd6c189 Mon Sep 17 00:00:00 2001 From: "Amit Bhavsar (Open ERP)" Date: Tue, 24 Apr 2012 18:57:32 +0530 Subject: [PATCH 017/726] [FIX] resubmitt account_patment : Fixes the IntegrityError Problem lp bug: https://launchpad.net/bugs/986088 fixed bzr revid: amb@tinyerp.com-20120424132732-6m8txac0d7yvn1f0 --- addons/account_payment/wizard/account_payment_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py index d62edc4e843..f2b553d3d26 100644 --- a/addons/account_payment/wizard/account_payment_order.py +++ b/addons/account_payment/wizard/account_payment_order.py @@ -87,7 +87,7 @@ class payment_order_create(osv.osv_memory): 'partner_id': line.partner_id and line.partner_id.id or False, 'communication': line.ref or '/', 'date': date_to_pay, - 'currency': line.invoice and line.invoice.currency_id.id or line.company_id.currency_id.id, + 'currency': line.invoice and line.invoice.currency_id.id or line.journal_id.currency.id or line.journal_id.company_id.currency_id.id, }, context=context) return {'type': 'ir.actions.act_window_close'} From b248452d71c2f9484d6b3d177f86139aea4e0b4f Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Fri, 27 Apr 2012 17:50:22 +0530 Subject: [PATCH 018/726] [FIX] account : Fixes the account on_change problem product tax should be overrite the account tax instead of adding lp bug: https://launchpad.net/bugs/960158 fixed bzr revid: amp@tinyerp.com-20120427122022-yzrojplo59358wuy --- addons/account/account_invoice.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index d06ba70bf02..d736d5c44b1 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1512,7 +1512,8 @@ class account_invoice_line(osv.osv): partner_id=partner_id, fposition_id=fposition_id) unique_tax_ids = set(tax_ids) if product_change_result and 'value' in product_change_result and 'invoice_line_tax_id' in product_change_result['value']: - unique_tax_ids |= set(product_change_result['value']['invoice_line_tax_id']) + # Product tax overrides account tax + unique_tax_ids = product_change_result['value']['invoice_line_tax_id'] return {'value':{'invoice_line_tax_id': list(unique_tax_ids)}} account_invoice_line() From 19ea613bce6bf27ab8f1edf6430aeb7aaedc3d9f Mon Sep 17 00:00:00 2001 From: Antoine <> Date: Mon, 30 Apr 2012 16:50:02 +0530 Subject: [PATCH 019/726] [FIX] stock :Fixes the searching problem in Inventory analysis lp bug: https://launchpad.net/bugs/985635 fixed bzr revid: amb@tinyerp.com-20120430112002-7qitbk228qodsnwy --- addons/stock/report/report_stock_move.py | 9 +++++---- addons/stock/report/report_stock_move_view.xml | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py index da6be7873c3..9915c30f132 100644 --- a/addons/stock/report/report_stock_move.py +++ b/addons/stock/report/report_stock_move.py @@ -166,6 +166,7 @@ class report_stock_inventory(osv.osv): help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\ \nThe state is \'Waiting\' if the move is waiting for another one.'), 'location_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True), + 'scrap_location': fields.boolean('scrap'), } def init(self, cr): tools.drop_view_if_exists(cr, 'report_stock_inventory') @@ -174,7 +175,7 @@ CREATE OR REPLACE view report_stock_inventory AS ( (SELECT min(m.id) as id, m.date as date, m.partner_id as partner_id, m.location_id as location_id, - m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, + m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location, m.company_id, m.state as state, m.prodlot_id as prodlot_id, @@ -191,12 +192,12 @@ CREATE OR REPLACE view report_stock_inventory AS ( LEFT JOIN stock_location l ON (m.location_id=l.id) GROUP BY m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, - m.prodlot_id, m.date, m.state, l.usage, m.company_id, pt.uom_id + m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id ) UNION ALL ( SELECT -m.id as id, m.date as date, m.partner_id as partner_id, m.location_dest_id as location_id, - m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, + m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location, m.company_id, m.state as state, m.prodlot_id as prodlot_id, coalesce(sum(pt.standard_price * m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as value, @@ -212,7 +213,7 @@ CREATE OR REPLACE view report_stock_inventory AS ( LEFT JOIN stock_location l ON (m.location_dest_id=l.id) GROUP BY m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, - m.prodlot_id, m.date, m.state, l.usage, m.company_id, pt.uom_id + m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id ) ); """) diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml index 01ef4a70289..5118ac78bb4 100644 --- a/addons/stock/report/report_stock_move_view.xml +++ b/addons/stock/report/report_stock_move_view.xml @@ -231,7 +231,7 @@ - + From 610e8e9a26aa7f869ed9b2d4513a74f103e442ad Mon Sep 17 00:00:00 2001 From: "Amit Bhavsar (Open ERP)" Date: Fri, 4 May 2012 12:37:55 +0530 Subject: [PATCH 020/726] [FIX] account_voucher : Fixes for the warning message lp bug: https://launchpad.net/bugs/930042 fixed bzr revid: amb@tinyerp.com-20120504070755-p2s6wjpjrrr3jplu --- addons/account_voucher/account_voucher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index 0191f5866ba..f60e76ae666 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -946,11 +946,11 @@ class account_voucher(osv.osv): if amount_residual > 0: account_id = line.voucher_id.company_id.expense_currency_exchange_account_id if not account_id: - raise osv.except_osv(_('Warning'),_("Unable to create accounting entry for currency rate difference. You have to configure the field 'Income Currency Rate' on the company! ")) + raise osv.except_osv(_('Warning'),_("Unable to create accounting entry for currency rate difference. You have to configure the field 'Expense Currency Rate' on the company! ")) else: account_id = line.voucher_id.company_id.income_currency_exchange_account_id if not account_id: - raise osv.except_osv(_('Warning'),_("Unable to create accounting entry for currency rate difference. You have to configure the field 'Expense Currency Rate' on the company! ")) + raise osv.except_osv(_('Warning'),_("Unable to create accounting entry for currency rate difference. You have to configure the field 'Income Currency Rate' on the company! ")) # Even if the amount_currency is never filled, we need to pass the foreign currency because otherwise # the receivable/payable account may have a secondary currency, which render this field mandatory account_currency_id = company_currency <> current_currency and current_currency or False From 6fcb0fe62b3ad61df0cdea0d1a19cf9cc17740d6 Mon Sep 17 00:00:00 2001 From: jose <> Date: Mon, 14 May 2012 12:39:10 +0530 Subject: [PATCH 021/726] [FIX] Pricelist: Fixes the problem on pricelist when template_id doesn't same with product_id lp bug: https://launchpad.net/bugs/997898 fixed bzr revid: amp@tinyerp.com-20120514070910-te6blf2bdmd5j2a5 --- addons/product/pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index ea29292f445..fb03c718e5c 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -204,7 +204,7 @@ class product_pricelist(osv.osv): if partner: partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' - partner_args = (partner, product_id) + partner_args = (partner, tmpl_id) else: partner_where = 'base <> -2 ' partner_args = () From e8ee0449f574a1b3153481902695a025a6b31f78 Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Fri, 18 May 2012 14:28:18 +0530 Subject: [PATCH 022/726] [FIX] stock : fixes some hidden bug on get_product_available function lp bug: https://launchpad.net/bugs/998631 fixed bzr revid: amp@tinyerp.com-20120518085818-8cuybt5d2qsgd3fg --- addons/stock/product.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/stock/product.py b/addons/stock/product.py index e7838bb490a..1450be9c800 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -237,7 +237,7 @@ class product_product(osv.osv): to_date = context.get('to_date',False) date_str = False date_values = False - where = [tuple(location_ids),tuple(location_ids),tuple(ids),tuple(states)] + where = [tuple(location_ids),tuple(ids),tuple(states)] if from_date and to_date: date_str = "date>=%s and date<=%s" where.append(tuple([from_date])) @@ -259,8 +259,7 @@ class product_product(osv.osv): cr.execute( 'select sum(product_qty), product_id, product_uom '\ 'from stock_move '\ - 'where location_id NOT IN %s '\ - 'and location_dest_id IN %s '\ + 'where location_dest_id IN %s '\ 'and product_id IN %s '\ '' + (prodlot_id and ('and prodlot_id = ' + str(prodlot_id)) or '') + ' '\ 'and state IN %s ' + (date_str and 'and '+date_str+' ' or '') +' '\ @@ -272,7 +271,6 @@ class product_product(osv.osv): 'select sum(product_qty), product_id, product_uom '\ 'from stock_move '\ 'where location_id IN %s '\ - 'and location_dest_id NOT IN %s '\ 'and product_id IN %s '\ '' + (prodlot_id and ('and prodlot_id = ' + str(prodlot_id)) or '') + ' '\ 'and state in %s ' + (date_str and 'and '+date_str+' ' or '') + ' '\ From bd72fd7d2f35e95792b9401da3ee973b1e9aa206 Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Tue, 22 May 2012 10:44:16 +0530 Subject: [PATCH 023/726] [FIX] marketing_campaign : Fix the problem when duplicate the partner workitem of this partner is also duplicated lp bug: https://launchpad.net/bugs/1002456 fixed bzr revid: amp@tinyerp.com-20120522051416-g5wq0t6kj2wgm8sj --- addons/marketing_campaign/res_partner.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/addons/marketing_campaign/res_partner.py b/addons/marketing_campaign/res_partner.py index 98ac53b7b29..8ae1ab8645a 100644 --- a/addons/marketing_campaign/res_partner.py +++ b/addons/marketing_campaign/res_partner.py @@ -29,7 +29,13 @@ class res_partner(osv.osv): 'partner_id', 'Workitems', readonly=True), } - + + def copy(self, cr, uid, id, default={}, context=None): + default.update({ + 'workitem_ids': [], + }) + return super(res_partner, self).copy(cr, uid, id, default=default, context=context) + res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From f6b512c6862ffe2506b954cf6f6b53b7aaf1fdf2 Mon Sep 17 00:00:00 2001 From: Quentin THEURET Date: Wed, 23 May 2012 13:04:39 +0200 Subject: [PATCH 024/726] [FIX] Fix no UoM restriction on Min/Max rules lp bug: https://launchpad.net/bugs/10003350 fixed bzr revid: qt@tempo-consulting.fr-20120523110439-zwq3zbq41kty7w8g --- addons/procurement/procurement.py | 35 ++++++++++++++++++++++++- addons/procurement/procurement_view.xml | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index aeab35be39b..9a27c425ed9 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -503,6 +503,19 @@ class stock_warehouse_orderpoint(osv.osv): result[orderpoint.id] = procurement_ids return result + def _check_product_uom(self, cr, uid, ids, context=None): + ''' + Check if the UoM has the same category as the product standard UoM + ''' + if not context: + context = {} + + for rule in self.browse(cr, uid, ids, context=context): + if rule.product_id.uom_id.category_id.id != rule.product_uom.category_id.id: + return False + + return True + _columns = { 'name': fields.char('Name', size=32, required=True), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the orderpoint without removing it."), @@ -535,6 +548,9 @@ class stock_warehouse_orderpoint(osv.osv): _sql_constraints = [ ('qty_multiple_check', 'CHECK( qty_multiple > 0 )', 'Qty Multiple must be greater than zero.'), ] + _constraints = [ + (_check_product_uom, 'You have to select a product UOM in the same category than the purchase UOM of the product', ['product_id', 'product_uom']), + ] def default_get(self, cr, uid, fields, context=None): res = super(stock_warehouse_orderpoint, self).default_get(cr, uid, fields, context) @@ -565,8 +581,25 @@ class stock_warehouse_orderpoint(osv.osv): """ if product_id: prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context) + d = {'product_uom': [('category_id', '=', prod.uom_id.category_id.id)]} v = {'product_uom': prod.uom_id.id} - return {'value': v} + return {'value': v, 'domain': d} + return {'domain': {'product_uom': []}} + + def onchange_uom(self, cr, uid, ids, product_id, uom_id, context=None): + ''' + Check if the UoM is compatible with product standard UoM + ''' + if uom_id and product_id: + product_obj = self.pool.get('product.product') + uom_obj = self.pool.get('product.uom') + + product = product_obj.browse(cr, uid, product_id, context=context) + uom = uom_obj.browse(cr, uid, uom_id, context=context) + + if product.uom_id.category_id.id != uom.category_id.id: + raise osv.except_osv(_('Wrong Product UOM !'), _('You have to select a product UOM in the same category than the purchase UOM of the product')) + return {} def copy(self, cr, uid, id, default=None, context=None): diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index c82032f2ee4..868231886cc 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -206,7 +206,7 @@ - + From cf3089812ccd8e6911667068e5ea9dc749ed6ee3 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre <> Date: Wed, 30 May 2012 11:35:48 +0530 Subject: [PATCH 025/726] [FIX] I have improve the error message in procurement lp bug: https://launchpad.net/bugs/1005987 fixed bzr revid: rmu@tinyerp.com-20120530060548-ijkmbmufuchofvax --- addons/procurement/procurement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 2263a441363..0e6b5440a9b 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -325,7 +325,7 @@ class procurement_order(osv.osv): for procurement in self.browse(cr, uid, ids, context=context): if procurement.product_qty <= 0.00: raise osv.except_osv(_('Data Insufficient !'), - _('Please check the quantity in procurement order(s), it should not be 0 or less!')) + _('Please check the quantity in procurement order(s) for the product "%s", it should not be 0 or less!' % procurement.product_id.name)) if procurement.product_id.type in ('product', 'consu'): if not procurement.move_id: source = procurement.location_id.id From 520c345840370b9751e95531cc1c22640299ee7b Mon Sep 17 00:00:00 2001 From: "Ravish Murari (OpenERP)" Date: Wed, 30 May 2012 12:07:14 +0530 Subject: [PATCH 026/726] [FIX] improve in routing work centers sequence lp bug: https://launchpad.net/bugs/1002105 fixed bzr revid: rmu@tinyerp.com-20120530063714-wt4nag4x4veay0lt --- addons/mrp/mrp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 3214cad5a5c..9dbec1a7470 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -106,6 +106,7 @@ class mrp_routing_workcenter(osv.osv): """ _name = 'mrp.routing.workcenter' _description = 'Work Center Usage' + _order = 'sequence' _columns = { 'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True), 'name': fields.char('Name', size=64, required=True), From 3509dcac662adbd24714755f2512421c236bc77e Mon Sep 17 00:00:00 2001 From: Ferdinand <> Date: Tue, 5 Jun 2012 12:33:06 +0530 Subject: [PATCH 027/726] [FIX] Stock : Fix for the Inventory line change in confirm state lp bug: https://launchpad.net/bugs/1008036 fixed bzr revid: amb@tinyerp.com-20120605070306-85km3dzzz63i90e9 --- addons/stock/stock_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index d9c8ccd8f39..6a721d71543 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -123,7 +123,7 @@ - + From 48166edeb8b950dd085dc7bb31f664f663a620fd Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 12:17:10 +0200 Subject: [PATCH 028/726] [FIX] rename ir.actions.url to match action's type bzr revid: xmo@openerp.com-20120608101710-ncwcmu9u72u7mxcy --- openerp/addons/base/ir/ir_actions.py | 2 +- openerp/addons/base/ir/ir_ui_menu.py | 2 +- openerp/tools/convert.py | 12 +++++++----- openerp/tools/yaml_import.py | 6 +++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index c74a5128bbf..88e70d4befb 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -375,7 +375,7 @@ class act_wizard(osv.osv): act_wizard() class act_url(osv.osv): - _name = 'ir.actions.url' + _name = 'ir.actions.act_url' _table = 'ir_act_url' _sequence = 'ir_actions_id_seq' _order = 'name' diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 15d250a7489..1ab2a88af9e 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -293,7 +293,7 @@ class ir_ui_menu(osv.osv): ('ir.actions.report.xml', 'ir.actions.report.xml'), ('ir.actions.act_window', 'ir.actions.act_window'), ('ir.actions.wizard', 'ir.actions.wizard'), - ('ir.actions.url', 'ir.actions.url'), + ('ir.actions.act_url', 'ir.actions.act_url'), ('ir.actions.server', 'ir.actions.server'), ('ir.actions.client', 'ir.actions.client'), ]), diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index c2c610c16af..0ac51266b07 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -384,18 +384,20 @@ form: module.record_id""" % (xml_id,) res = {'name': name, 'url': url, 'target':target} - id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + act_url = "ir.actions.act_url" + id = self.pool.get('ir.model.data')._update(cr, self.uid, act_url, self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) # ir_set if (not rec.get('menu') or eval(rec.get('menu','False'))) and id: keyword = str(rec.get('keyword','') or 'client_action_multi') - value = 'ir.actions.url,'+str(id) + value = act_url + ',' + str(id) replace = rec.get("replace",'') or True - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id) + self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, [ + act_url], value, replace=replace, isobject=True, xml_id=xml_id) elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False): # Special check for URL having attribute menu=False on update - value = 'ir.actions.url,'+str(id) - self._remove_ir_values(cr, url, value, "ir.actions.url") + value = act_url + ',' + str(id) + self._remove_ir_values(cr, url, value, act_url) def _tag_act_window(self, cr, rec, data_node=None): name = rec.get('name','').encode('utf-8') diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 136d1bcee7b..37fcae60113 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -728,15 +728,15 @@ class YamlInterpreter(object): res = {'name': node.name, 'url': node.url, 'target': node.target} id = self.pool.get('ir.model.data')._update(self.cr, 1, \ - "ir.actions.url", self.module, res, node.id, mode=self.mode) + "ir.actions.act_url", self.module, res, node.id, mode=self.mode) self.id_map[node.id] = int(id) # ir_set if (not node.menu or eval(node.menu)) and id: keyword = node.keyword or 'client_action_multi' - value = 'ir.actions.url,%s' % id + value = 'ir.actions.act_url,%s' % id replace = node.replace or True self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', \ - keyword, node.url, ["ir.actions.url"], value, replace=replace, \ + keyword, node.url, ["ir.actions.act_url"], value, replace=replace, \ noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) def process_ir_set(self, node): From 4ed79f3457a0252dcee4780385dc474ff2af356e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 12:17:14 +0200 Subject: [PATCH 029/726] [FIX] rename ir.actions.url to match action's type bzr revid: xmo@openerp.com-20120608101714-lf3o4mmvllmi4ge0 --- addons/web/controllers/main.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 1ccba0c9867..6eb8ed94909 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1467,10 +1467,6 @@ class Binary(openerpweb.Controller): class Action(openerpweb.Controller): _cp_path = "/web/action" - - action_mapping = { - "ir.actions.act_url": "ir.actions.url", - } @openerpweb.jsonrequest def load(self, req, action_id, do_not_eval=False): @@ -1483,9 +1479,7 @@ class Action(openerpweb.Controller): if action_type[0]['type'] == 'ir.actions.report.xml': ctx.update({'bin_size': True}) ctx.update(context) - action_model = action_type[0]['type'] - action_model = Action.action_mapping.get(action_model, action_model) - action = req.session.model(action_model).read([action_id], False, ctx) + action = req.session.model(action_type[0]['type']).read([action_id], False, ctx) if action: value = clean_action(req, action[0], do_not_eval) return {'result': value} From 4f5f0de47d153a616ec2cb3d33e70db2de411289 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 12:17:15 +0200 Subject: [PATCH 030/726] [FIX] rename ir.actions.url to match action's type bzr revid: xmo@openerp.com-20120608101715-ri3upmywr6kl850q --- addons/document_ftp/wizard/ftp_browse.py | 2 +- addons/document_ftp/wizard/ftp_configuration.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/document_ftp/wizard/ftp_browse.py b/addons/document_ftp/wizard/ftp_browse.py index b1120bc6511..8260424d653 100644 --- a/addons/document_ftp/wizard/ftp_browse.py +++ b/addons/document_ftp/wizard/ftp_browse.py @@ -39,7 +39,7 @@ class document_ftp_browse(osv.osv_memory): data_pool = self.pool.get('ir.model.data') aid = data_pool._get_id(cr, uid, 'document_ftp', 'action_document_browse') aid = data_pool.browse(cr, uid, aid, context=context).res_id - ftp_url = self.pool.get('ir.actions.url').browse(cr, uid, aid, context=context) + ftp_url = self.pool.get('ir.actions.act_url').browse(cr, uid, aid, context=context) url = ftp_url.url and ftp_url.url.split('ftp://') or [] if url: url = url[1] diff --git a/addons/document_ftp/wizard/ftp_configuration.py b/addons/document_ftp/wizard/ftp_configuration.py index 5da2ddf11e8..d0679973c5a 100644 --- a/addons/document_ftp/wizard/ftp_configuration.py +++ b/addons/document_ftp/wizard/ftp_configuration.py @@ -44,7 +44,7 @@ class document_ftp_configuration(osv.osv_memory): # Update the action for FTP browse. aid = data_pool._get_id(cr, uid, 'document_ftp', 'action_document_browse') aid = data_pool.browse(cr, uid, aid, context=context).res_id - self.pool.get('ir.actions.url').write(cr, uid, [aid], + self.pool.get('ir.actions.act_url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost:8021')+'/' + cr.dbname+'/'}) document_ftp_configuration() From a59da4d4767b6778769dfd276ab6044aac1fe6f1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 12:38:15 +0200 Subject: [PATCH 031/726] [REM] ir_set from _tag_url's convert Hinges on @menu (not allowed on the url tag), @keyword (not allowed either) and sets the url on the url bzr revid: xmo@openerp.com-20120608103815-n20dhponzinhr7xf --- openerp/tools/convert.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 0ac51266b07..bc16bba1591 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -384,20 +384,8 @@ form: module.record_id""" % (xml_id,) res = {'name': name, 'url': url, 'target':target} - act_url = "ir.actions.act_url" - id = self.pool.get('ir.model.data')._update(cr, self.uid, act_url, self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.act_url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) - # ir_set - if (not rec.get('menu') or eval(rec.get('menu','False'))) and id: - keyword = str(rec.get('keyword','') or 'client_action_multi') - value = act_url + ',' + str(id) - replace = rec.get("replace",'') or True - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, [ - act_url], value, replace=replace, isobject=True, xml_id=xml_id) - elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False): - # Special check for URL having attribute menu=False on update - value = act_url + ',' + str(id) - self._remove_ir_values(cr, url, value, act_url) def _tag_act_window(self, cr, rec, data_node=None): name = rec.get('name','').encode('utf-8') From 3e289407af96a460c780ddaf5a47f63bf447252d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 13:29:03 +0200 Subject: [PATCH 032/726] [FIX] document_ftp: forgot to save edition of XML bzr revid: xmo@openerp.com-20120608112903-3dhrjatn1ufhukh4 --- addons/document_ftp/wizard/ftp_configuration_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/document_ftp/wizard/ftp_configuration_view.xml b/addons/document_ftp/wizard/ftp_configuration_view.xml index 66707024c52..a1a6df3dc6a 100644 --- a/addons/document_ftp/wizard/ftp_configuration_view.xml +++ b/addons/document_ftp/wizard/ftp_configuration_view.xml @@ -1,6 +1,6 @@ - + Browse Files ftp://localhost:8021/ From b773ed3fafdd1d7773a8ae8fae0377304a988a65 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 8 Jun 2012 13:31:07 +0200 Subject: [PATCH 033/726] [FIX] model access for act_url bzr revid: xmo@openerp.com-20120608113107-nelgblnh0w1cff0q --- openerp/addons/base/security/ir.model.access.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 8b906ba48a5..9e9c8abe513 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -98,8 +98,8 @@ "access_workflow_workitem_all","workflow_workitem_all","model_workflow_workitem",,1,1,1,1 "access_ir_actions_act_window_view_all","ir_actions_act_window_view_all","model_ir_actions_act_window_view",,1,0,0,0 "access_ir_actions_act_window_view_group_system","ir_actions_act_window_view_group_system","model_ir_actions_act_window_view","group_system",1,1,1,1 -"access_ir_actions_url_all","ir_actions_url_all","model_ir_actions_url",,1,0,0,0 -"access_ir_actions_url_group_system","ir_actions_url_group_system","model_ir_actions_url","group_system",1,1,1,1 +"access_ir_actions_act_url_all","ir_actions_act_url_all","model_ir_actions_act_url",,1,0,0,0 +"access_ir_actions_act_url_group_system","ir_actions_act_url_group_system","model_ir_actions_act_url","group_system",1,1,1,1 "access_ir_server_object_lines_all","ir_server_object_lines_all","model_ir_server_object_lines",,1,0,0,0 "access_ir_server_object_lines_group_system","ir_server_object_lines_group_system","model_ir_server_object_lines","group_system",1,1,1,1 "access_ir_actions_server_all","ir_actions_server_all","model_ir_actions_server",,1,0,0,0 From 1a48187c3bb5f693fa039a2dd71bdbfd17c816da Mon Sep 17 00:00:00 2001 From: "Ferdinand @ Camptocamp" <> Date: Mon, 11 Jun 2012 12:03:52 +0530 Subject: [PATCH 034/726] [FIX] Improve in message of method update_journal_check in acount_move_line lp bug: https://launchpad.net/bugs/1011178 fixed bzr revid: rmu@tinyerp.com-20120611063352-agnsyq9l50fp883x --- addons/account/account_move_line.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 892747c849f..a0981c6100a 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1188,7 +1188,9 @@ class account_move_line(osv.osv): result = cr.fetchall() for (state,) in result: if state == 'done': - raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed journal.')) + journal = journal_obj.read(cr, uid, journal_id, ['name']) + period = period_obj.read(cr, uid, period_id, ['name']) + raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period['name'],journal['name']))) if not result: journal = journal_obj.browse(cr, uid, journal_id, context=context) period = period_obj.browse(cr, uid, period_id, context=context) From eee05a71e69a079c7f568d31190274101e40dba1 Mon Sep 17 00:00:00 2001 From: Ferdinand <> Date: Mon, 11 Jun 2012 16:53:42 +0530 Subject: [PATCH 035/726] [FIX] Improve the code lp bug: https://launchpad.net/bugs/1011178 fixed bzr revid: rmu@tinyerp.com-20120611112342-26mx7amrg6x78l4i --- addons/account/account_move_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index a0981c6100a..65da0dc601b 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1190,7 +1190,7 @@ class account_move_line(osv.osv): if state == 'done': journal = journal_obj.read(cr, uid, journal_id, ['name']) period = period_obj.read(cr, uid, period_id, ['name']) - raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period['name'],journal['name']))) + raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period['name'],journal['name']))) if not result: journal = journal_obj.browse(cr, uid, journal_id, context=context) period = period_obj.browse(cr, uid, period_id, context=context) From ddc30d6ae14f7546ac3d179eecae611284670a60 Mon Sep 17 00:00:00 2001 From: Serpent Consulting Services Date: Fri, 22 Jun 2012 03:13:11 +0530 Subject: [PATCH 036/726] [FIX] Audittrail : The method reag_group also need to be skipped while passing through audittrail scanner lp bug: https://launchpad.net/bugs/1013229 fixed bzr revid: support@serpentcs.com-20120621214311-etvwtf0umk2wz1qp --- addons/audittrail/audittrail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index aee9fbd9305..c995372209b 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -483,7 +483,7 @@ class audittrail_objects_proxy(object_proxy): if len(rule['user_id']) == 0 or uid in rule['user_id']: if rule.get('log_'+method,0): return True - elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create'): + elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): if rule['log_action']: return True From 3d71723ada44186b56ad041d43e569cbe29de4a2 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 2 Jul 2012 15:11:47 +0530 Subject: [PATCH 037/726] [FIX]Add weight,weight_net on stock.picking.in(incoming shipment) and stock.picking.out (delivery order) In Delivery module lp bug: https://launchpad.net/bugs/1016378 fixed bzr revid: fka@tinyerp.com-20120702094147-qnrbc84k7fdfycrk --- addons/delivery/delivery_view.xml | 44 +++++++++++++++++++++---------- addons/delivery/stock.py | 28 ++++++++++++++++++++ addons/stock/stock.py | 2 +- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml index 5e54f74f7f1..3cbe3f1f2c7 100644 --- a/addons/delivery/delivery_view.xml +++ b/addons/delivery/delivery_view.xml @@ -183,6 +183,14 @@ + + + + + + + + @@ -196,6 +204,10 @@ + + + + @@ -211,19 +223,6 @@ - - stock.picking_withweight.internal.move.form.view - form - stock.picking - - - - - - - - - stock.move.form.weight form @@ -280,6 +279,23 @@ - + + + delivery.stock.picking_withcarrier.in.form.view + form + stock.picking.in + + + + + + + + + + + + + diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py index 64ebf0ff9fa..a50226cb583 100644 --- a/addons/delivery/stock.py +++ b/addons/delivery/stock.py @@ -202,5 +202,33 @@ class stock_picking_out(osv.osv): 'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32), 'number_of_packages': fields.integer('Number of Packages'), } +stock_picking_out() + +class stock_picking_in(osv.osv): + _inherit = 'stock.picking.in' + + def _cal_weight(self, cr, uid, ids, name, args, context=None): + return self.pool.get('stock.picking')._cal_weight(cr, uid, ids, name, args, context=context) + + + def _get_picking_line(self, cr, uid, ids, context=None): + return self.pool.get('stock.picking')._get_picking_line(cr, uid, ids, context=context) + + _columns = { + + 'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight', + store={ + 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20), + 'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20), + }), + 'weight_net': fields.function(_cal_weight, type='float', string='Net Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight', + store={ + 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20), + 'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20), + }), + + } +stock_picking_in() + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/stock.py b/addons/stock/stock.py index a279b8bea6c..077d1b0719f 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2841,7 +2841,7 @@ class stock_picking_in(osv.osv): _name = "stock.picking.in" _inherit = "stock.picking" _table = "stock_picking" - _description = "Incomming Shipments" + _description = "Incoming Shipments" def check_access_rights(self, cr, uid, operation, raise_exception=True): #override in order to redirect the check of acces rights on the stock.picking object From d1d191da05ceab661bff808bb772c113b3c13f47 Mon Sep 17 00:00:00 2001 From: "Pinakin Nayi (OpenERP)" Date: Wed, 4 Jul 2012 17:36:49 +0530 Subject: [PATCH 038/726] [FIX]calandar-event:validation lp bug: https://launchpad.net/bugs/1020561 fixed bzr revid: pna@tinyerp.com-20120704120649-5tm4qlducduc52ff --- addons/base_calendar/base_calendar.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index bbededc8eaf..cc2ee08c305 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1111,6 +1111,16 @@ rule or repeating pattern of time to exclude from the recurring rule."), 'user_id': lambda self, cr, uid, ctx: uid, 'organizer': default_organizer, } + + def _check_closing_date(self, cr, uid, ids, context=None): + for event in self.browse(cr, uid, ids, context=context): + if event.date_deadline < event.date: + return False + return True + + _constraints = [ + (_check_closing_date, 'Error ! Closing Date cannot be set before Beginning Date.', ['date_deadline']), + ] def get_recurrent_ids(self, cr, uid, select, domain, limit=100, context=None): """Gives virtual event ids for recurring events based on value of Recurrence Rule From 8531184a9295da42eebf5b7ad2a7a2d997427fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1nSoriano?= <> Date: Mon, 9 Jul 2012 15:08:11 +0530 Subject: [PATCH 039/726] [FIX] Fixes problem of adding product in supplier invoice when product_visible_discount installed lp bug: https://launchpad.net/bugs/1021436 fixed bzr revid: jir@jir-desktop-20120709093811-ojp32jo3g19v2kf5 --- addons/product_visible_discount/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product_visible_discount/__openerp__.py b/addons/product_visible_discount/__openerp__.py index d957c6d87ed..5a3b3518220 100644 --- a/addons/product_visible_discount/__openerp__.py +++ b/addons/product_visible_discount/__openerp__.py @@ -33,7 +33,7 @@ Example: If the check box is checked, we will have on the sale order line: Unit price=450, Discount=50,00, Net price=225 If the check box is unchecked, we will have on Sale Order and Invoice lines: Unit price=225, Discount=0,00, Net price=225 """, - "depends": ["sale"], + "depends": ["sale","purchase"], "demo_xml": [], "update_xml": ['product_visible_discount_view.xml'], "auto_install": False, From 63ee6a74a91a630f5b5049f10ae67291df85f760 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 9 Jul 2012 17:09:54 +0530 Subject: [PATCH 040/726] [IMP] project : column project_task_history_cumulative.project_id does not exist. lp bug: https://launchpad.net/bugs/1022509 fixed bzr revid: mdi@tinyerp.com-20120709113954-l17wlurxovz6z05i --- addons/project/report/project_cumulative.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/addons/project/report/project_cumulative.xml b/addons/project/report/project_cumulative.xml index 3f7f3b26d96..535fbaf5f87 100644 --- a/addons/project/report/project_cumulative.xml +++ b/addons/project/report/project_cumulative.xml @@ -9,7 +9,6 @@ - @@ -63,9 +62,7 @@ - - From e2ba0eb95c38a16839836deeaa9a73b58221e9aa Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 9 Jul 2012 18:42:59 +0530 Subject: [PATCH 041/726] [IMP] project : Revert the unneccessary changes. bzr revid: mdi@tinyerp.com-20120709131259-c9fl7g3hgwhxutgb --- addons/project/report/project_cumulative.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/project/report/project_cumulative.xml b/addons/project/report/project_cumulative.xml index 535fbaf5f87..177e945bc93 100644 --- a/addons/project/report/project_cumulative.xml +++ b/addons/project/report/project_cumulative.xml @@ -9,6 +9,7 @@ + From f9ad472466645f8ab9dc4dbc66a049042d97b8f9 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 11 Jul 2012 12:40:54 +0530 Subject: [PATCH 042/726] [ADD] add new http service translation. bzr revid: tpa@tinyerp.com-20120711071054-rfreaxwys8b1fqbc --- openerp/service/web_services.py | 50 +++++++++++++++++++++++++++++++++ openerp/tools/translate.py | 17 +++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 330bb86dcfc..6762426d8cd 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -777,6 +777,55 @@ class report_spool(netsvc.ExportService): else: raise Exception, 'ReportNotFound' +class translation(netsvc.ExportService): + + def __init__(self, name="translation"): + netsvc.ExportService.__init__(self, name) + + def exp_load(self, db, modules, langs, flag=None, context=None): + translated_data = [] + cr = pooler.get_db(db).cursor() + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + cr.commit() + cr.close() + return translated_data + + def dispatch(self, method, params): + if method in ['load']: + # No security check for these methods + pass + else: + raise KeyError("Method not found: %s" % method) + fn = getattr(self, 'exp_'+method) + return fn(*params) + +translation() def start_web_services(): db() @@ -784,6 +833,7 @@ def start_web_services(): objects_proxy() wizard() report_spool() + translation() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index eb5dbe24077..0d3802bd5c0 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -43,6 +43,7 @@ import misc from misc import UpdateableStr from misc import SKIPPED_ELEMENT_TYPES import osutil +import babel.messages.pofile _logger = logging.getLogger(__name__) @@ -842,12 +843,22 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): try: fileobj = misc.file_open(filename) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + if flag == 'web': + transl = {"messages":[]} + po = babel.messages.pofile.read_po(fileobj) + for x in po: + if x.id and x.string and "openerp-web" in x.auto_comments: + transl["messages"].append({'id': x.id, 'string': x.string}) + return transl + else: + fileformat = os.path.splitext(filename)[-1][1:].lower() + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) fileobj.close() return r except IOError: From 67aa9fa31a7c64bf59a1b942ecbe6dc83c878241 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 11 Jul 2012 12:44:05 +0530 Subject: [PATCH 043/726] [IMP] load translation using 'translation' http service bzr revid: tpa@tinyerp.com-20120711071405-g0biuqlctedlbcs9 --- addons/web/controllers/main.py | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 412ea9abda2..5d7aa93f3a5 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -353,25 +353,15 @@ class WebClient(openerpweb.Controller): langs = lang.split(separator) langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)] - transs = {} - for addon_name in mods: - transl = {"messages":[]} - transs[addon_name] = transl - addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] - for l in langs: - f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") - if not os.path.exists(f_name): - continue - try: - with open(f_name) as t_file: - po = babel.messages.pofile.read_po(t_file) - except Exception: - continue - for x in po: - if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) - return {"modules": transs, - "lang_parameters": lang_obj} + messages = {} + for mod in mods: + messages[mod] = {"messages":[]} + proxy = req.session.proxy("translation") + trans = proxy.load(req.session._db, [mod], langs, "web") + if trans: + messages[mod] = trans + return {"modules": {'messages': messages}, + "lang_parameters": lang_obj} @openerpweb.jsonrequest def version_info(self, req): From 4ea3ad65b24ad8b89d1c06d36bffc40e3ea9a865 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 10:51:11 +0530 Subject: [PATCH 044/726] [ADD] added module field in ir.translation and improved code for that. bzr revid: tpa@tinyerp.com-20120712052111-5qq9noxd5vd9dlwv --- openerp/addons/base/ir/ir_translation.py | 20 ++++++++++---------- openerp/addons/base/module/module.py | 4 ++-- openerp/service/web_services.py | 4 ++-- openerp/tools/translate.py | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 61e40e807d4..2f8f87a0a2a 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -70,7 +70,6 @@ class ir_translation_import_cursor(object): cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), - imd_module VARCHAR(64), imd_name VARCHAR(128) ) INHERITS (%s) ''' % (self._table_name, self._parent_table)) @@ -80,10 +79,10 @@ class ir_translation_import_cursor(object): self._cr.execute("INSERT INTO " + self._table_name \ + """(name, lang, res_id, src, type, - imd_model, imd_module, imd_name, value) + imd_model, module, imd_name, value) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", (ddict['name'], ddict['lang'], ddict.get('res_id'), ddict['src'], ddict['type'], - ddict.get('imd_model'), ddict.get('imd_module'), ddict.get('imd_name'), + ddict.get('imd_model'), ddict.get('module'), ddict.get('imd_name'), ddict['value'])) def finish(self): @@ -101,18 +100,18 @@ class ir_translation_import_cursor(object): SET res_id = imd.res_id FROM ir_model_data AS imd WHERE ti.res_id IS NULL - AND ti.imd_module IS NOT NULL AND ti.imd_name IS NOT NULL + AND ti.module IS NOT NULL AND ti.imd_name IS NOT NULL - AND ti.imd_module = imd.module AND ti.imd_name = imd.name + AND ti.module = imd.module AND ti.imd_name = imd.name AND ti.imd_model = imd.model; """ % self._table_name) if self._debug: - cr.execute("SELECT imd_module, imd_model, imd_name FROM %s " \ - "WHERE res_id IS NULL AND imd_module IS NOT NULL" % self._table_name) + cr.execute("SELECT module, imd_model, imd_name FROM %s " \ + "WHERE res_id IS NULL AND module IS NOT NULL" % self._table_name) for row in cr.fetchall(): _logger.debug("ir.translation.cursor: missing res_id for %s. %s/%s ", *row) - cr.execute("DELETE FROM %s WHERE res_id IS NULL AND imd_module IS NOT NULL" % \ + cr.execute("DELETE FROM %s WHERE res_id IS NULL AND module IS NOT NULL" % \ self._table_name) # Records w/o res_id must _not_ be inserted into our db, because they are @@ -132,8 +131,8 @@ class ir_translation_import_cursor(object): # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value) - SELECT name, lang, res_id, src, type, value + cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module) + SELECT name, lang, res_id, src, type, value, module FROM %s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); """ % (self._parent_table, self._table_name, self._parent_table, find_expr)) @@ -167,6 +166,7 @@ class ir_translation(osv.osv): 'type': fields.selection(TRANSLATION_TYPE, string='Type', size=16, select=True), 'src': fields.text('Source'), 'value': fields.text('Translation Value'), + 'module': fields.char('Module Name', size=128), } _sql_constraints = [ ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)', diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 392850f7b77..1a3b41513b4 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -620,7 +620,7 @@ class module(osv.osv): f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, context=context) + tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -630,7 +630,7 @@ class module(osv.osv): f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, context=context2) + tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 6762426d8cd..2dbaa67a425 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -799,7 +799,7 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +809,7 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 0d3802bd5c0..83576d8d7b9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -843,7 +843,7 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) pool = pooler.get_pool(cr.dbname) @@ -858,7 +858,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() return r except IOError: @@ -866,7 +866,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): _logger.error("couldn't read translation file %s", filename) return None -def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, context=None): +def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None): """Populates the ir_translation table.""" if verbose: _logger.info('loading translation file for language %s', lang) @@ -896,7 +896,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, break elif fileformat == 'po': reader = TinyPoFile(fileobj) - f = ['type', 'name', 'res_id', 'src', 'value'] + f = ['type', 'name', 'res_id', 'src', 'value', 'module'] else: _logger.error('Bad file format: %s', fileformat) raise Exception(_('Bad file format')) @@ -929,6 +929,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if res_id and isinstance(res_id, (int, long)) \ or (isinstance(res_id, basestring) and res_id.isdigit()): dic['res_id'] = int(res_id) + dic['module'] = module_name else: try: tmodel = dic['name'].split(',')[0] @@ -938,9 +939,8 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, tmodule = dic_module tname = res_id dic['imd_model'] = tmodel - dic['imd_module'] = tmodule + dic['module'] = tmodule dic['imd_name'] = tname - dic['res_id'] = None except Exception: _logger.warning("Could not decode resource for %s, please fix the po file.", From d87adc497e11e3f5c22da7069720b6f9270d7ada Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 14:28:38 +0530 Subject: [PATCH 045/726] [IMP] improved code to get translation from database. bzr revid: tpa@tinyerp.com-20120712085838-pqzj86fptp96eag6 --- openerp/service/web_services.py | 10 +++++++--- openerp/tools/translate.py | 13 ++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 2dbaa67a425..7f6b201d9c3 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,7 +783,7 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = [] + translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() for module_name in modules: modpath = openerp.modules.get_module_path(module_name) @@ -799,7 +799,9 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +811,9 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 83576d8d7b9..4067133e2a9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,12 +849,11 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web': - transl = {"messages":[]} - po = babel.messages.pofile.read_po(fileobj) - for x in po: - if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) + if flag == 'web' and module_name == 'web': + transl = [] + trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) + for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): + transl.append({'id': trans.src, 'string': trans.value}) return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() @@ -913,7 +912,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, # dictionary which holds values for this line of the csv file # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ..., - # 'src': ..., 'value': ...} + # 'src': ..., 'value': ..., 'module':...} dic = {'lang': lang} dic_module = False for i in range(len(f)): From 20646e9104a1e36a2375f0b688dc5a5ed18665b1 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:01:30 +0530 Subject: [PATCH 046/726] [IMP] move load function to the ir_translation.py bzr revid: tpa@tinyerp.com-20120712093130-rcis1aamb7bbptdd --- openerp/addons/base/ir/ir_translation.py | 36 ++++++++++++++++++++++++ openerp/service/web_services.py | 35 ++--------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 2f8f87a0a2a..404dfb842a3 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -22,6 +22,7 @@ from osv import fields, osv import tools import logging +import openerp.modules _logger = logging.getLogger(__name__) @@ -322,6 +323,41 @@ class ir_translation(osv.osv): """ Return a cursor-like object for fast inserting translations """ return ir_translation_import_cursor(cr, uid, self, context=context) + + def load(self, cr, modules, langs, flag, context=None): + translated_data = {'messages':[]} + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + return translated_data ir_translation() diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 7f6b201d9c3..17935efda54 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,39 +783,10 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() - for module_name in modules: - modpath = openerp.modules.get_module_path(module_name) - if not modpath: - # unable to find the module. we skip - continue - for lang in langs: - iso_lang = tools.get_iso_codes(lang) - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') + translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data From 976944bce2f4a39f0d1f0b22737a2b0603479b32 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:21:31 +0530 Subject: [PATCH 047/726] [IMP] improved code in module.py to load translation. bzr revid: tpa@tinyerp.com-20120712095131-3tt25snidvafflhb --- openerp/addons/base/ir/ir_translation.py | 2 +- openerp/addons/base/module/module.py | 30 +++--------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 404dfb842a3..ad7d7013127 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -324,7 +324,7 @@ class ir_translation(osv.osv): """ return ir_translation_import_cursor(cr, uid, self, context=context) - def load(self, cr, modules, langs, flag, context=None): + def load(self, cr, modules, langs, flag=None, context=None): translated_data = {'messages':[]} for module_name in modules: modpath = openerp.modules.get_module_path(module_name) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 1a3b41513b4..963fb292946 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -596,8 +596,8 @@ class module(osv.osv): def update_translations(self, cr, uid, ids, filter_lang=None, context=None): if context is None: context = {} + pool = pooler.get_pool(cr.dbname) if not filter_lang: - pool = pooler.get_pool(cr.dbname) lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) filter_lang = [lang.code for lang in lang_obj.browse(cr, uid, lang_ids)] @@ -607,32 +607,8 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - modpath = modules.get_module_path(mod.name) - if not modpath: - # unable to find the module. we skip - continue - for lang in filter_lang: - iso_lang = tools.get_iso_codes(lang) - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) + traslation_obj = pool.get('ir.translation') + traslation_obj.load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): From f0f4ba6d413ce89e016b26895f1e3fb62450d2ae Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 16:11:10 +0530 Subject: [PATCH 048/726] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120712104110-wot1evq0affpx2tp --- addons/web/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 5d7aa93f3a5..eb60b178ad2 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -360,7 +360,7 @@ class WebClient(openerpweb.Controller): trans = proxy.load(req.session._db, [mod], langs, "web") if trans: messages[mod] = trans - return {"modules": {'messages': messages}, + return {"modules": messages, "lang_parameters": lang_obj} @openerpweb.jsonrequest From 4bbbef1929fc41b9928690ac77112ec5aa3db452 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 16:29:55 +0530 Subject: [PATCH 049/726] [IMP] improved code for load translation when run web without embedded mode. bzr revid: tpa@tinyerp.com-20120712105955-szwm5vb49va6o4dp --- addons/web/controllers/main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index eb60b178ad2..75feed44c69 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -360,6 +360,24 @@ class WebClient(openerpweb.Controller): trans = proxy.load(req.session._db, [mod], langs, "web") if trans: messages[mod] = trans + # keep loading from .po (Reason to run web without embedded mode) + if not messages['web']['messages']: + for addon_name in mods: + transl = {'messages':[]} + messages[addon_name] = transl + addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] + for l in langs: + f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") + if not os.path.exists(f_name): + continue + try: + with open(f_name) as t_file: + po = babel.messages.pofile.read_po(t_file) + except Exception: + continue + for x in po: + if x.id and x.string and "openerp-web" in x.auto_comments: + transl["messages"].append({'id': x.id, 'string': x.string}) return {"modules": messages, "lang_parameters": lang_obj} From bc76991e24edc42353fc637624fa7ff4bfa8a34f Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:53:08 +0530 Subject: [PATCH 050/726] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120712132308-1qvurv572sxmsnqe --- openerp/addons/base/ir/ir_translation.py | 8 ++------ openerp/tools/translate.py | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index ad7d7013127..0a3124b36ce 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -340,9 +340,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -352,9 +350,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 4067133e2a9..517b39e6999 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -857,9 +857,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) + trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return r + return [] except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From e9c78767dd87c003c6e93f679e531e34b90d04c7 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:55:42 +0530 Subject: [PATCH 051/726] [IMP] improved code bzr revid: tpa@tinyerp.com-20120712132542-c19ysod7jm5jmukc --- addons/web/controllers/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 75feed44c69..6c0e2e4dc9b 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -357,9 +357,7 @@ class WebClient(openerpweb.Controller): for mod in mods: messages[mod] = {"messages":[]} proxy = req.session.proxy("translation") - trans = proxy.load(req.session._db, [mod], langs, "web") - if trans: - messages[mod] = trans + messages[mod] = proxy.load(req.session._db, [mod], langs, "web") # keep loading from .po (Reason to run web without embedded mode) if not messages['web']['messages']: for addon_name in mods: From c17ea49de98e6cbe2ba2c760f3bc70323bfc9202 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:57:00 +0530 Subject: [PATCH 052/726] [IMP] improved code bzr revid: tpa@tinyerp.com-20120712132700-zc4co6o4plhzoi60 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 517b39e6999..e9b830302f7 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,7 +849,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web' and module_name == 'web': + if flag == 'web': transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): From f05ee5dfdb3dc5ec3f2db9b7685e5ed9e8e8fc01 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 11:23:30 +0530 Subject: [PATCH 053/726] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713055330-avz6ebzuqvcpxdd5 --- openerp/addons/base/module/module.py | 5 ++--- openerp/service/web_services.py | 4 +--- openerp/tools/translate.py | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 963fb292946..bbf3f3f5b64 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -594,9 +594,9 @@ class module(osv.osv): self.write(cr, uid, [mod_browse.id], {'category_id': p_id}) def update_translations(self, cr, uid, ids, filter_lang=None, context=None): + pool = pooler.get_pool(cr.dbname) if context is None: context = {} - pool = pooler.get_pool(cr.dbname) if not filter_lang: lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) @@ -607,8 +607,7 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - traslation_obj = pool.get('ir.translation') - traslation_obj.load(cr, [mod.name], filter_lang, context=context) + pool.get('ir.translation').load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 17935efda54..0cfcf468a2b 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -784,9 +784,7 @@ class translation(netsvc.ExportService): def exp_load(self, db, modules, langs, flag=None, context=None): cr = pooler.get_db(db).cursor() - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') - translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) + translated_data = pooler.get_pool(db).get('ir.translation').load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index e9b830302f7..bbada8c2efc 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -846,20 +846,18 @@ def trans_generate(lang, modules, cr): def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') + traslation_obj = pooler.get_pool(cr.dbname).get('ir.translation') _logger.info("loading %s", filename) + transl = [] if flag == 'web': - transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): transl.append({'id': trans.src, 'string': trans.value}) - return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return [] + return transl except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From 402ba23000ed38f2d4c95d5b240d6327d70b3731 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 12:25:21 +0530 Subject: [PATCH 054/726] [IMP] improved code to retun traslation in proper format from server bzr revid: tpa@tinyerp.com-20120713065521-07a7qdfxfio673cq --- openerp/addons/base/ir/ir_translation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 0a3124b36ce..cd6fa271852 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -325,8 +325,9 @@ class ir_translation(osv.osv): return ir_translation_import_cursor(cr, uid, self, context=context) def load(self, cr, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} + translated_data = {} for module_name in modules: + translated_data[module_name] = {'messages':[]} modpath = openerp.modules.get_module_path(module_name) if not modpath: # unable to find the module. we skip @@ -340,7 +341,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -350,7 +351,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data From 0d4bd736e1bd8c8acb78f63e190111b1c72b05af Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 12:30:48 +0530 Subject: [PATCH 055/726] [IMP] improved code to get formeted traslation from server. bzr revid: tpa@tinyerp.com-20120713070048-7yxm3fcajemiingc --- addons/web/controllers/main.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6c0e2e4dc9b..7cde4040e4f 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -353,11 +353,8 @@ class WebClient(openerpweb.Controller): langs = lang.split(separator) langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)] - messages = {} - for mod in mods: - messages[mod] = {"messages":[]} - proxy = req.session.proxy("translation") - messages[mod] = proxy.load(req.session._db, [mod], langs, "web") + proxy = req.session.proxy("translation") + messages = proxy.load(req.session._db, mods, langs, "web") # keep loading from .po (Reason to run web without embedded mode) if not messages['web']['messages']: for addon_name in mods: From 8383d6a2459588b332ecdcb0a26c38f92c5ab317 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 14:58:38 +0530 Subject: [PATCH 056/726] [IMP] Fetch only traslated and distinct strings using sql. bzr revid: tpa@tinyerp.com-20120713092838-5th251msbdkgjdnb --- openerp/tools/translate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index bbada8c2efc..11801326ba3 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,9 +850,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) - for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): - transl.append({'id': trans.src, 'string': trans.value}) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + for src, value in cr.fetchall(): + transl.append({'id': src, 'string': value}) else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) From 48a344c1e8d88b005eaf29128890196fd096b441 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 15:24:48 +0530 Subject: [PATCH 057/726] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713095448-ghr750h2jk9ivsj2 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 11801326ba3..25e80e260fa 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,7 +850,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND lang='%s' AND value != ''"% (module_name,lang)) for src, value in cr.fetchall(): transl.append({'id': src, 'string': value}) else: From 822dd5f17755080bbd0e4c29969a255a84206dc5 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 13 Jul 2012 19:38:35 +0200 Subject: [PATCH 058/726] Take into account the new 'active' field on ir.model.access. bzr revid: alexis@via.ecp.fr-20120713173835-azbi8iorq1ps2x35 --- addons/share/ir_model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/share/ir_model.py b/addons/share/ir_model.py index 008dd424fa5..0d90aec3eb7 100644 --- a/addons/share/ir_model.py +++ b/addons/share/ir_model.py @@ -40,6 +40,7 @@ class ir_model_access(osv.Model): LEFT JOIN ir_module_category c ON (c.id=g.category_id) WHERE m.model=%s AND + a.active IS true AND (g.share IS NULL or g.share IS false) AND a.perm_''' + access_mode, (model_name,)) return [('%s/%s' % x) if x[0] else x[1] for x in cr.fetchall()] From 58e20e9c8f0f40b93a0d4dd1ff68666d49311949 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 11:30:56 +0530 Subject: [PATCH 059/726] [IMP] improved code to load data from po. bzr revid: tpa@tinyerp.com-20120716060056-3az6awpd6gw39hii --- addons/web/controllers/main.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 7cde4040e4f..024360ce5e6 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -355,14 +355,11 @@ class WebClient(openerpweb.Controller): proxy = req.session.proxy("translation") messages = proxy.load(req.session._db, mods, langs, "web") - # keep loading from .po (Reason to run web without embedded mode) - if not messages['web']['messages']: - for addon_name in mods: - transl = {'messages':[]} - messages[addon_name] = transl - addons_path = openerpweb.addons_manifest[addon_name]['addons_path'] + for mod in messages: + if not messages[mod]['messages']: + addons_path = openerpweb.addons_manifest[mod]['addons_path'] for l in langs: - f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po") + f_name = os.path.join(addons_path, mod, "i18n", l + ".po") if not os.path.exists(f_name): continue try: @@ -372,7 +369,7 @@ class WebClient(openerpweb.Controller): continue for x in po: if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) + messages[mod]["messages"].append({'id': x.id, 'string': x.string}) return {"modules": messages, "lang_parameters": lang_obj} From d931a099ac4551a4d24724a09ecc12d3951a82b6 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:04:58 +0530 Subject: [PATCH 060/726] [ADD] added test case for translation load in tests_xmlrpc.py. bzr revid: tpa@tinyerp.com-20120716103458-p2l9p38g4ubl7d2i --- openerp/tests/common.py | 1 + openerp/tests/test_xmlrpc.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index ef5b0586136..351645c41f2 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -72,6 +72,7 @@ class RpcCase(unittest2.TestCase): self.proxy.common_61 = xmlrpclib.ServerProxy(url_61 + 'common') self.proxy.db_61 = xmlrpclib.ServerProxy(url_61 + 'db') self.proxy.model_61 = xmlrpclib.ServerProxy(url_61 + 'model/' + DB) + self.proxy.translation_61 = xmlrpclib.ServerProxy(url_61 + 'translation') @classmethod def generate_database_name(cls): diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 37655e72718..5f73325fe4c 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -71,6 +71,11 @@ class test_xmlrpc(common.RpcCase): """ assert self.proxy.db_60.drop(ADMIN_PASSWORD, DB) is True + def test_xmlrpc_61_translation_load(self): + """ Try a load translation service like web. """ + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + assert messages + if __name__ == '__main__': unittest2.main() From 74fd43b82c211d416fef8f9b1ff10bc43d5aaab8 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:13:05 +0530 Subject: [PATCH 061/726] [IMP] change language. bzr revid: tpa@tinyerp.com-20120716104305-ws8igxbfx7m0bwy9 --- openerp/tests/test_xmlrpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 5f73325fe4c..70ac6b1f75f 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -73,7 +73,7 @@ class test_xmlrpc(common.RpcCase): def test_xmlrpc_61_translation_load(self): """ Try a load translation service like web. """ - messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['en_US'], 'web') assert messages if __name__ == '__main__': From 8de8ed96cae4fc6b8d27d21e20e3aaf0f01cd40d Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Mon, 23 Jul 2012 13:36:51 +0200 Subject: [PATCH 062/726] [IMP] l10n_nl: define property reserve & profit/loss in chart of accounts template lp bug: https://launchpad.net/bugs/1027896 fixed bzr revid: stefan@therp.nl-20120723113651-aluz7rnmj2bui00n --- addons/l10n_nl/account_chart_netherlands.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/l10n_nl/account_chart_netherlands.xml b/addons/l10n_nl/account_chart_netherlands.xml index 4c9fe63308b..f1c14fc4ad8 100644 --- a/addons/l10n_nl/account_chart_netherlands.xml +++ b/addons/l10n_nl/account_chart_netherlands.xml @@ -4100,6 +4100,7 @@ + + + + mail.message.subtype.tree + mail.message.subtype + tree + 10 + + + + + + + + + + + mail.message.subtype.form + mail.message.subtype + form + + + + + + + + + + + + + + + + + + + + Subtypes + mail.message.subtype + form + tree,form + + + + + + From 64240ea54b755de3f78353047c387f44610dda51 Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Mon, 30 Jul 2012 12:48:23 +0530 Subject: [PATCH 070/726] [FIX] stock : Phyical inventory should check_tracking if incoming track true lp bug: https://launchpad.net/bugs/1030037 fixed bzr revid: amp@tinyerp.com-20120730071823-ucsozzcqln2ijgju --- addons/stock/stock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9752f0c78f4..e768c33e969 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1590,7 +1590,8 @@ class stock_move(osv.osv): (move.product_id.track_production and move.location_id.usage == 'production') or \ (move.product_id.track_production and move.location_dest_id.usage == 'production') or \ (move.product_id.track_incoming and move.location_id.usage == 'supplier') or \ - (move.product_id.track_outgoing and move.location_dest_id.usage == 'customer') \ + (move.product_id.track_outgoing and move.location_dest_id.usage == 'customer') or \ + (move.product_id.track_incoming and move.location_id.usage == 'inventory') \ )): return False return True From b5c3a5327fcceb6d6c8843cd148e2f72d728ca08 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 14:38:04 +0530 Subject: [PATCH 071/726] [ADD] Add many2many subtype_id field in mail.subscription bzr revid: fka@tinyerp.com-20120730090804-x3lpju3fq11hg703 --- addons/mail/mail_subscription.py | 4 ++++ addons/mail/mail_subscription_view.xml | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/addons/mail/mail_subscription.py b/addons/mail/mail_subscription.py index fc82af879a9..a3baa024ef0 100644 --- a/addons/mail/mail_subscription.py +++ b/addons/mail/mail_subscription.py @@ -42,6 +42,10 @@ class mail_subscription(osv.osv): help='Id of the followed resource'), 'user_id': fields.many2one('res.users', string='Related User', ondelete='cascade', required=True, select=1), + 'subtype_ids': fields.many2many('mail.message.subtype', + 'mail_message_subtyp_rel', + 'subscription_id', 'subtype_id', 'Subtype', + help = "linking some subscription to several subtype for projet/task"), } class mail_notification(osv.osv): diff --git a/addons/mail/mail_subscription_view.xml b/addons/mail/mail_subscription_view.xml index c3d79d48308..b88b8c25258 100644 --- a/addons/mail/mail_subscription_view.xml +++ b/addons/mail/mail_subscription_view.xml @@ -20,6 +20,27 @@ + + mail.subscription.form + mail.subscription + form + +
+ + + + + + + + + + + + +
+
+
From ad7c07875787ed2e5a4c60d9173741b9e75a9ba7 Mon Sep 17 00:00:00 2001 From: "Amit (OpenERP)" Date: Mon, 30 Jul 2012 15:00:20 +0530 Subject: [PATCH 072/726] [FIX] account : Fixed the unicode decode error on search of account.account object lp bug: https://launchpad.net/bugs/1029316 fixed bzr revid: amp@tinyerp.com-20120730093020-ujffkjldt1uuflip --- addons/account/account.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account/account.py b/addons/account/account.py index cbba0237c78..412345e0bc0 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -30,6 +30,7 @@ from osv import fields, osv import decimal_precision as dp from tools.translate import _ from tools.float_utils import float_round +import tools _logger = logging.getLogger(__name__) @@ -225,7 +226,7 @@ class account_account(osv.osv): while pos < len(args): if args[pos][0] == 'code' and args[pos][1] in ('like', 'ilike') and args[pos][2]: - args[pos] = ('code', '=like', str(args[pos][2].replace('%', ''))+'%') + args[pos] = ('code', '=like', tools.ustr(args[pos][2].replace('%', ''))+'%') if args[pos][0] == 'journal_id': if not args[pos][2]: del args[pos] From c494b78f7776f64bde8d4cdefa82f7cdda867548 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 15:05:50 +0530 Subject: [PATCH 073/726] [ADD] Add many2one subtype_id field in mail.message bzr revid: fka@tinyerp.com-20120730093550-h9xnithn5h3eq5nk --- addons/mail/mail_message.py | 1 + addons/mail/mail_message_view.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index b96b6e3791e..14de51b39ab 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -230,6 +230,7 @@ class mail_message(osv.Model): select=True, ondelete='set null', help="Parent message, used for displaying as threads with hierarchy"), 'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'), + 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype', select = True), } _defaults = { diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 986bb4bef38..374b97624b1 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -152,6 +152,7 @@ + From eca351d07aa9febc810764069b1fe380a5057245 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Wed, 1 Aug 2012 14:26:48 +0200 Subject: [PATCH 074/726] [FIX] Case insensitive user names in LDAP create duplicate users in OpenERP lp bug: https://launchpad.net/bugs/985606 fixed bzr revid: stefan@therp.nl-20120801122648-14mqu4x7xb3gd7p5 --- addons/users_ldap/users_ldap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/users_ldap/users_ldap.py b/addons/users_ldap/users_ldap.py index e4615907c79..0846bb408f6 100644 --- a/addons/users_ldap/users_ldap.py +++ b/addons/users_ldap/users_ldap.py @@ -180,7 +180,7 @@ class CompanyLDAP(osv.osv): """ user_id = False - login = tools.ustr(login) + login = tools.ustr(login.lower()) cr.execute("SELECT id, active FROM res_users WHERE login=%s", (login,)) res = cr.fetchone() if res: From 8f9facb0248bf810c9d5de4caa043b22c5f0b094 Mon Sep 17 00:00:00 2001 From: Date: Fri, 3 Aug 2012 16:52:38 +0200 Subject: [PATCH 075/726] [FIX] use partner_id.title.name (closes lp:1032662) bzr revid: alexandre.fayolle@camptocamp.com-20120803145238-irc87p22ij6sigzp --- addons/report_webkit_sample/report/report_webkit_html.mako | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/report_webkit_sample/report/report_webkit_html.mako b/addons/report_webkit_sample/report/report_webkit_html.mako index 164a697f386..3ffca9f669c 100644 --- a/addons/report_webkit_sample/report/report_webkit_html.mako +++ b/addons/report_webkit_sample/report/report_webkit_html.mako @@ -8,7 +8,7 @@ %for inv in objects : <% setLang(inv.partner_id.lang) %> - + From 24264e759d42ab47f0b4b7f11a1341a3108c08b8 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 6 Aug 2012 16:10:15 +0530 Subject: [PATCH 076/726] [IMP] make changes into thread file bzr revid: rma@tinyerp.com-20120806104015-et9znlwd5lrqggfn --- addons/mail/mail_message.py | 3 ++- addons/mail/mail_thread.py | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 14de51b39ab..8b88647b108 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -275,6 +275,7 @@ class mail_message(osv.Model): def create(self, cr, uid, values, context=None): self.check(cr, uid, [], mode='create', context=context, values=values) return super(mail_message, self).create(cr, uid, values, context) + def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'): self.check(cr, uid, ids, 'read', context=context) @@ -392,7 +393,7 @@ class mail_message(osv.Model): def cancel(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state':'cancel'}, context=context) - + def process_email_queue(self, cr, uid, ids=None, context=None): """Send immediately queued messages, committing after each message is sent - this is not transactional and should diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 1655ab98afb..0afddc747d6 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -176,7 +176,7 @@ class mail_thread(osv.Model): email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) return msg_id - + #TODO :in message creation: in push method: push only if user is subscriber (current case) and if user is sucscribed to the subtype (to add) def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') # get body @@ -327,7 +327,7 @@ class mail_thread(osv.Model): if partner_ids is None: partner_ids = [] mail_partner_ids = [(6, 0, partner_ids)] - + data = { 'subject': subject, 'body_text': body_text or (hasattr(thread, 'description') and thread.description or ''), @@ -363,7 +363,6 @@ class mail_thread(osv.Model): new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context)) return new_msg_ids - def message_append_dict(self, cr, uid, ids, msg_dict, context=None): """Creates a new mail.message attached to the given threads (``ids``), with the contents of ``msg_dict``, by calling ``message_append`` @@ -874,6 +873,10 @@ class mail_thread(osv.Model): :param user_ids: a list of user_ids; if not set, subscribe uid instead """ + # TODO:Update Massage Subscribe and add paramenter subtype_ids + # if subtype_ids is False: add default ones (res_model = self._name, default = True) + # in method: if user_id already subscriber, update its subscription with subtype_ids + subscription_obj = self.pool.get('mail.subscription') to_subscribe_uids = [uid] if user_ids is None else user_ids create_ids = [] @@ -883,7 +886,8 @@ class mail_thread(osv.Model): if user_id in already_subscribed_user_ids: continue create_ids.append(subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context)) return create_ids - + #TODO : Add method : add message_subscribe_udpate_subtypes(..., user_id, subtype_ids): + def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None): """ Unsubscribe the user (or user_ids) from the current document. @@ -900,7 +904,8 @@ class mail_thread(osv.Model): if not to_delete_sub_ids: return False return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context=context) - + #TODO : Add Method : add message_subscribeption_remove_subtype(..., user_id, subtype_id): + #TODO : Add method : add message_subscription_remove_subtype_name(.., user_id, subtype_name) #------------------------------------------------------ # Notification API #------------------------------------------------------ From d00b0a9d0e9f81f89fb5a222add0b55884fa917f Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Wed, 8 Aug 2012 17:58:12 +0530 Subject: [PATCH 077/726] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120808122812-v0hw80phlnb9es75 --- addons/mail/mail_thread.py | 315 ++++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 144 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 0afddc747d6..3e5bfabe350 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -62,33 +62,33 @@ class mail_thread(osv.Model): _name = 'mail.thread' _description = 'Email Thread' - def _get_message_ids(self, cr, uid, ids, name, args, context=None): + def _get_message_ids(self, cr, uid, ids, name, args, context = None): res = {} for id in ids: - message_ids = self.message_search(cr, uid, [id], context=context) - subscriber_ids = self.message_get_subscribers(cr, uid, [id], context=context) + message_ids = self.message_search(cr, uid, [id], context = context) + subscriber_ids = self.message_get_subscribers(cr, uid, [id], context = context) res[id] = { 'message_ids': message_ids, 'message_summary': "9 %d + %d" % (len(message_ids), len(subscriber_ids)), } return res - def _search_message_ids(self, cr, uid, obj, name, args, context=None): + def _search_message_ids(self, cr, uid, obj, name, args, context = None): msg_obj = self.pool.get('mail.message') - msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', args[0][2]), ('model', '=', self._name)], context=context) + msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', args[0][2]), ('model', '=', self._name)], context = context) return [('id', 'in', msg_ids)] _columns = { - 'message_ids': fields.function(_get_message_ids, method=True, - fnct_search=_search_message_ids, - type='one2many', obj='mail.message', _fields_id = 'res_id', - string='Temp messages', multi="_get_message_ids", - help="Functional field holding messages related to the current document."), + 'message_ids': fields.function(_get_message_ids, method = True, + fnct_search = _search_message_ids, + type = 'one2many', obj = 'mail.message', _fields_id = 'res_id', + string = 'Temp messages', multi = "_get_message_ids", + help = "Functional field holding messages related to the current document."), 'message_state': fields.boolean('Read', - help="When checked, new messages require your attention."), - 'message_summary': fields.function(_get_message_ids, method=True, - type='text', string='Summary', multi="_get_message_ids", - help="Holds the Chatter summary (number of messages, ...). "\ + help = "When checked, new messages require your attention."), + 'message_summary': fields.function(_get_message_ids, method = True, + type = 'text', string = 'Summary', multi = "_get_message_ids", + help = "Holds the Chatter summary (number of messages, ...). "\ "This summary is directly in html format in order to "\ "be inserted in kanban views."), } @@ -101,23 +101,23 @@ class mail_thread(osv.Model): # Automatic subscription when creating/reading #------------------------------------------------------ - def create(self, cr, uid, vals, context=None): + def create(self, cr, uid, vals, context = None): """Automatically subscribe the creator """ - thread_id = super(mail_thread, self).create(cr, uid, vals, context=context) + thread_id = super(mail_thread, self).create(cr, uid, vals, context = context) if thread_id: - self.message_subscribe(cr, uid, [thread_id], [uid], context=context) + self.message_subscribe(cr, uid, [thread_id], [uid], context = context) return thread_id - def write(self, cr, uid, ids, vals, context=None): + def write(self, cr, uid, ids, vals, context = None): """Automatically subscribe the writer""" if isinstance(ids, (int, long)): ids = [ids] - write_res = super(mail_thread, self).write(cr, uid, ids, vals, context=context); + write_res = super(mail_thread, self).write(cr, uid, ids, vals, context = context); if write_res: - self.message_subscribe(cr, uid, ids, [uid], context=context) + self.message_subscribe(cr, uid, ids, [uid], context = context) return write_res; - def unlink(self, cr, uid, ids, context=None): + def unlink(self, cr, uid, ids, context = None): """Override unlink, to automatically delete - subscriptions - messages @@ -128,19 +128,19 @@ class mail_thread(osv.Model): subscr_obj = self.pool.get('mail.subscription') msg_obj = self.pool.get('mail.message') # delete subscriptions - subscr_to_del_ids = subscr_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - subscr_obj.unlink(cr, uid, subscr_to_del_ids, context=context) + subscr_to_del_ids = subscr_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context = context) + subscr_obj.unlink(cr, uid, subscr_to_del_ids, context = context) # delete messages and notifications - msg_to_del_ids = msg_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], context=context) - msg_obj.unlink(cr, uid, msg_to_del_ids, context=context) + msg_to_del_ids = msg_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], context = context) + msg_obj.unlink(cr, uid, msg_to_del_ids, context = context) - return super(mail_thread, self).unlink(cr, uid, ids, context=context) + return super(mail_thread, self).unlink(cr, uid, ids, context = context) #------------------------------------------------------ # mail.message wrappers and tools #------------------------------------------------------ - def message_create(self, cr, uid, thread_id, vals, context=None): + def message_create(self, cr, uid, thread_id, vals, context = None): """ OpenChatter: wrapper of mail.message create method - creates the mail.message - automatically subscribe the message writer @@ -155,57 +155,58 @@ class mail_thread(osv.Model): # automatically subscribe the writer of the message if vals['user_id']: - self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) + self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context = context) # create message - msg_id = message_obj.create(cr, uid, vals, context=context) + msg_id = message_obj.create(cr, uid, vals, context = context) # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) + self.message_create_set_unread(cr, uid, [thread_id], context = context) # special: if install mode, do not push demo data if context.get('install_mode', False): return msg_id # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context = context) for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) + notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context = context) # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context = context) return msg_id + #TODO :in message creation: in push method: push only if user is subscriber (current case) and if user is sucscribed to the subtype (to add) - def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): + def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context = None): subscription_obj = self.pool.get('mail.subscription') # get body body = new_msg_vals.get('body_html', '') if new_msg_vals.get('content_subtype') == 'html' else new_msg_vals.get('body_text', '') # get subscribers - notif_user_ids = self.message_get_subscribers(cr, uid, thread_ids, context=context) + notif_user_ids = self.message_get_subscribers(cr, uid, thread_ids, context = context) # add users requested via parsing message (@login) - notif_user_ids += self.message_parse_users(cr, uid, body, context=context) + notif_user_ids += self.message_parse_users(cr, uid, body, context = context) # add users requested to perform an action (need_action mechanism) if hasattr(self, 'get_needaction_user_ids'): - user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context=context) + user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context = context) for id, user_ids in user_ids_dict.iteritems(): notif_user_ids += user_ids # add users notified of the parent messages (because: if parent message contains @login, login must receive the replies) if new_msg_vals.get('parent_id'): notif_obj = self.pool.get('mail.notification') - parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context=context) - parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context=context) + parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context = context) + parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context = context) notif_user_ids += [parent_notif['user_id'][0] for parent_notif in parent_notifs] # remove duplicate entries notif_user_ids = list(set(notif_user_ids)) return notif_user_ids - def message_parse_users(self, cr, uid, string, context=None): + def message_parse_users(self, cr, uid, string, context = None): """Parse message content - if find @login -(^|\s)@((\w|@|\.)*)-: returns the related ids this supports login that are emails (such as @raoul@grobedon.net) @@ -213,14 +214,14 @@ class mail_thread(osv.Model): regex = re.compile('(^|\s)@((\w|@|\.)*)') login_lst = [item[1] for item in regex.findall(string)] if not login_lst: return [] - user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context=context) + user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context = context) return user_ids #------------------------------------------------------ # Generic message api #------------------------------------------------------ - def message_capable_models(self, cr, uid, context=None): + def message_capable_models(self, cr, uid, context = None): ret_dict = {} for model_name in self.pool.obj_list(): model = self.pool.get(model_name) @@ -228,13 +229,13 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, - type='email', email_date=None, parent_id=False, - content_subtype='plain', state=None, - partner_ids=None, email_from=False, email_to=False, - email_cc=None, email_bcc=None, reply_to=None, - headers=None, message_id=False, references=None, - attachments=None, original=None, context=None): + def message_append(self, cr, uid, threads, subject, body_text = None, body_html = None, + type = 'email', subtype_id = False, email_date = None, parent_id = False, + content_subtype = 'plain', state = None, + partner_ids = None, email_from = False, email_to = False, + email_cc = None, email_bcc = None, reply_to = None, + headers = None, message_id = False, references = None, + attachments = None, original = None, context = None): """ Creates a new mail.message through message_create. The new message is attached to the current mail.thread, containing all the details passed as parameters. All attachments will be attached to the @@ -298,7 +299,7 @@ class mail_thread(osv.Model): if all(isinstance(thread_id, (int, long)) for thread_id in threads): model = context.get('thread_model') or self._name model_pool = self.pool.get(model) - threads = model_pool.browse(cr, uid, threads, context=context) + threads = model_pool.browse(cr, uid, threads, context = context) ir_attachment = self.pool.get('ir.attachment') mail_message = self.pool.get('mail.message') @@ -318,7 +319,7 @@ class mail_thread(osv.Model): 'res_model': thread._name, 'res_id': thread.id, } - to_attach.append(ir_attachment.create(cr, uid, data_attach, context=context)) + to_attach.append(ir_attachment.create(cr, uid, data_attach, context = context)) # find related partner: partner_id column in thread object, or self is res.partner model partner_id = ('partner_id' in thread._columns.keys()) and (thread.partner_id and thread.partner_id.id or False) or False if not partner_id and thread._name == 'res.partner': @@ -361,9 +362,10 @@ class mail_thread(osv.Model): 'reply_to': reply_to, 'original': original, }) - new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context)) + new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context = context)) return new_msg_ids - def message_append_dict(self, cr, uid, ids, msg_dict, context=None): + + def message_append_dict(self, cr, uid, ids, msg_dict, context = None): """Creates a new mail.message attached to the given threads (``ids``), with the contents of ``msg_dict``, by calling ``message_append`` with the mail details. All attachments in msg_dict will be @@ -382,9 +384,10 @@ class mail_thread(osv.Model): return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), body_text = msg_dict.get('body_text'), - body_html= msg_dict.get('body_html'), + body_html = msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), type = msg_dict.get('type', 'email'), + subtype_id = msg_dict.get('subtype_id', False), content_subtype = msg_dict.get('content_subtype'), state = msg_dict.get('state'), partner_ids = msg_dict.get('partner_ids'), @@ -406,7 +409,7 @@ class mail_thread(osv.Model): # Message loading #------------------------------------------------------ - def _message_search_ancestor_ids(self, cr, uid, ids, child_ids, ancestor_ids, context=None): + def _message_search_ancestor_ids(self, cr, uid, ids, child_ids, ancestor_ids, context = None): """ Given message child_ids ids, find their ancestors until ancestor_ids using their parent_id relationship. @@ -425,13 +428,13 @@ class mail_thread(osv.Model): ] message_obj = self.pool.get('mail.message') - messages_temp = message_obj.read(cr, uid, child_ids, ['id', 'parent_id'], context=context) + messages_temp = message_obj.read(cr, uid, child_ids, ['id', 'parent_id'], context = context) parent_ids = _get_parent_ids(messages_temp, ancestor_ids, child_ids) child_ids += parent_ids cur_iter = 0; max_iter = 100; # avoid infinite loop while (parent_ids and (cur_iter < max_iter)): cur_iter += 1 - messages_temp = message_obj.read(cr, uid, parent_ids, ['id', 'parent_id'], context=context) + messages_temp = message_obj.read(cr, uid, parent_ids, ['id', 'parent_id'], context = context) parent_ids = _get_parent_ids(messages_temp, ancestor_ids, child_ids) child_ids += parent_ids if (cur_iter > max_iter): @@ -440,7 +443,7 @@ class mail_thread(osv.Model): "message graph, leading to a curious error. Have fun.") return child_ids - def message_search_get_domain(self, cr, uid, ids, context=None): + def message_search_get_domain(self, cr, uid, ids, context = None): """ OpenChatter feature: get the domain to search the messages related to a document. mail.thread defines the default behavior as being messages with model = self._name, id in ids. @@ -449,8 +452,8 @@ class mail_thread(osv.Model): """ return ['&', ('res_id', 'in', ids), ('model', '=', self._name)] - def message_search(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, domain=None, count=False, context=None): + def message_search(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, domain = None, count = False, context = None): """ OpenChatter feature: return thread messages ids according to the search domain given by ``message_search_get_domain``. @@ -477,17 +480,17 @@ class mail_thread(osv.Model): default domain. :param limit, offset, count, context: as usual """ - search_domain = self.message_search_get_domain(cr, uid, ids, context=context) + search_domain = self.message_search_get_domain(cr, uid, ids, context = context) if domain: search_domain += domain message_obj = self.pool.get('mail.message') - message_res = message_obj.search(cr, uid, search_domain, limit=limit, offset=offset, count=count, context=context) + message_res = message_obj.search(cr, uid, search_domain, limit = limit, offset = offset, count = count, context = context) if not count and fetch_ancestors: - message_res += self._message_search_ancestor_ids(cr, uid, ids, message_res, ancestor_ids, context=context) + message_res += self._message_search_ancestor_ids(cr, uid, ids, message_res, ancestor_ids, context = context) return message_res - def message_read(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, domain=None, context=None): + def message_read(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, domain = None, context = None): """ OpenChatter feature: read the messages related to some threads. This method is used mainly the Chatter widget, to directly have read result instead of searching then reading. @@ -495,8 +498,8 @@ class mail_thread(osv.Model): Please see message_search for more information about the parameters. """ message_ids = self.message_search(cr, uid, ids, fetch_ancestors, ancestor_ids, - limit, offset, domain, context=context) - messages = self.pool.get('mail.message').read(cr, uid, message_ids, context=context) + limit, offset, domain, context = context) + messages = self.pool.get('mail.message').read(cr, uid, message_ids, context = context) """ Retrieve all attachments names """ map_id_to_name = dict((attachment_id, '') for message in messages for attachment_id in message['attachment_ids']) @@ -506,7 +509,7 @@ class mail_thread(osv.Model): map_id_to_name[attach_id] = '' # use empty string as a placeholder ids = map_id_to_name.keys() - names = self.pool.get('ir.attachment').name_get(cr, uid, ids, context=context) + names = self.pool.get('ir.attachment').name_get(cr, uid, ids, context = context) # convert the list of tuples into a dictionnary for name in names: @@ -520,13 +523,13 @@ class mail_thread(osv.Model): msg["attachments"].append({'id': attach_id, 'name': map_id_to_name[attach_id]}) # Set the threads as read - self.message_check_and_set_read(cr, uid, ids, context=context) + self.message_check_and_set_read(cr, uid, ids, context = context) # Sort and return the messages - messages = sorted(messages, key=lambda d: (-d['id'])) + messages = sorted(messages, key = lambda d: (-d['id'])) return messages - def message_get_pushed_messages(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, msg_search_domain=[], context=None): + def message_get_pushed_messages(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, msg_search_domain = [], context = None): """ OpenChatter: wall: get the pushed notifications and used them to fetch messages to display on the wall. @@ -550,13 +553,13 @@ class mail_thread(osv.Model): # compose final domain domain = [('user_id', '=', uid)] + msg_search_domain # get notifications - notification_ids = notification_obj.search(cr, uid, domain, limit=limit, offset=offset, context=context) - notifications = notification_obj.browse(cr, uid, notification_ids, context=context) + notification_ids = notification_obj.search(cr, uid, domain, limit = limit, offset = offset, context = context) + notifications = notification_obj.browse(cr, uid, notification_ids, context = context) msg_ids = [notification.message_id.id for notification in notifications] # get messages - msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context=context) - if (fetch_ancestors): msg_ids = self._message_search_ancestor_ids(cr, uid, ids, msg_ids, ancestor_ids, context=context) - msgs = msg_obj.read(cr, uid, msg_ids, context=context) + msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context = context) + if (fetch_ancestors): msg_ids = self._message_search_ancestor_ids(cr, uid, ids, msg_ids, ancestor_ids, context = context) + msgs = msg_obj.read(cr, uid, msg_ids, context = context) return msgs #------------------------------------------------------ @@ -564,9 +567,9 @@ class mail_thread(osv.Model): #------------------------------------------------------ # message_process will call either message_new or message_update. - def message_process(self, cr, uid, model, message, custom_values=None, - save_original=False, strip_attachments=False, - context=None): + def message_process(self, cr, uid, model, message, custom_values = None, + save_original = False, strip_attachments = False, + context = None): """Process an incoming RFC2822 email message related to the given thread model, relying on ``mail.message.parse()`` for the parsing operation, and then calling ``message_new`` @@ -606,7 +609,7 @@ class mail_thread(osv.Model): if isinstance(message, unicode): message = message.encode('utf-8') msg_txt = email.message_from_string(message) - msg = mail_message.parse_message(msg_txt, save_original=save_original, context=context) + msg = mail_message.parse_message(msg_txt, save_original = save_original, context = context) # update state msg['state'] = 'received' @@ -619,7 +622,7 @@ class mail_thread(osv.Model): if hasattr(model_pool, 'message_new'): return model_pool.message_new(cr, uid, msg, custom_values, - context=context) + context = context) res_id = False if msg.get('references') or msg.get('in-reply-to'): references = msg.get('references') or msg.get('in-reply-to') @@ -640,19 +643,19 @@ class mail_thread(osv.Model): res_id = res_id if model_pool.exists(cr, uid, res_id): if hasattr(model_pool, 'message_update'): - model_pool.message_update(cr, uid, [res_id], msg, {}, context=context) + model_pool.message_update(cr, uid, [res_id], msg, {}, context = context) else: # referenced thread was not found, we'll have to create a new one res_id = False if not res_id: res_id = create_record(msg) # To forward the email to other followers - self.message_forward(cr, uid, model, [res_id], msg_txt, context=context) + self.message_forward(cr, uid, model, [res_id], msg_txt, context = context) # Set as Unread - model_pool.message_mark_as_unread(cr, uid, [res_id], context=context) + model_pool.message_mark_as_unread(cr, uid, [res_id], context = context) return res_id - def message_new(self, cr, uid, msg_dict, custom_values=None, context=None): + def message_new(self, cr, uid, msg_dict, custom_values = None, context = None): """Called by ``message_process`` when a new message is received for a given thread model, if the message did not belong to an existing thread. @@ -681,17 +684,17 @@ class mail_thread(osv.Model): context = {} model = context.get('thread_model') or self._name model_pool = self.pool.get(model) - fields = model_pool.fields_get(cr, uid, context=context) - data = model_pool.default_get(cr, uid, fields, context=context) + fields = model_pool.fields_get(cr, uid, context = context) + data = model_pool.default_get(cr, uid, fields, context = context) if 'name' in fields and not data.get('name'): data['name'] = msg_dict.get('from', '') if custom_values and isinstance(custom_values, dict): data.update(custom_values) - res_id = model_pool.create(cr, uid, data, context=context) - self.message_append_dict(cr, uid, [res_id], msg_dict, context=context) + res_id = model_pool.create(cr, uid, data, context = context) + self.message_append_dict(cr, uid, [res_id], msg_dict, context = context) return res_id - def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None): + def message_update(self, cr, uid, ids, msg_dict, update_vals = None, context = None): """ Called by ``message_process`` when a new message is received for an existing thread. The default behavior is to create a new mail.message in the given thread (by calling @@ -711,10 +714,10 @@ class mail_thread(osv.Model): update (instead of the current model). """ if update_vals: - self.write(cr, uid, ids, update_vals, context=context) - return self.message_append_dict(cr, uid, ids, msg_dict, context=context) + self.write(cr, uid, ids, update_vals, context = context) + return self.message_append_dict(cr, uid, ids, msg_dict, context = context) - def message_thread_followers(self, cr, uid, ids, context=None): + def message_thread_followers(self, cr, uid, ids, context = None): """ Returns a list of email addresses of the people following this thread, including the sender of each mail, and the people who were in CC of the messages, if any. @@ -722,7 +725,7 @@ class mail_thread(osv.Model): res = {} if isinstance(ids, (str, int, long)): ids = [long(ids)] - for thread in self.browse(cr, uid, ids, context=context): + for thread in self.browse(cr, uid, ids, context = context): l = set() for message in thread.message_ids: l.add((message.user_id and message.user_id.user_email) or '') @@ -731,7 +734,7 @@ class mail_thread(osv.Model): res[thread.id] = filter(None, l) return res - def message_forward(self, cr, uid, model, thread_ids, msg, email_error=False, context=None): + def message_forward(self, cr, uid, model, thread_ids, msg, email_error = False, context = None): """Sends an email to all people following the given threads. The emails are forwarded immediately, not queued for sending, and not archived. @@ -746,7 +749,7 @@ class mail_thread(osv.Model): model_pool = self.pool.get(model) smtp_server_obj = self.pool.get('ir.mail_server') mail_message = self.pool.get('mail.message') - for res in model_pool.browse(cr, uid, thread_ids, context=context): + for res in model_pool.browse(cr, uid, thread_ids, context = context): if hasattr(model_pool, 'message_thread_followers'): followers = model_pool.message_thread_followers(cr, uid, [res.id])[res.id] else: @@ -765,7 +768,7 @@ class mail_thread(osv.Model): smtp_from, = to_email(msg['from']) msg['from'] = smtp_from - msg['to'] = ", ".join(forward_to) + msg['to'] = ", ".join(forward_to) msg['message-id'] = tools.generate_tracking_message_id(res.id) if not smtp_server_obj.send_email(cr, uid, msg) and email_error: subj = msg['subject'] @@ -775,7 +778,7 @@ class mail_thread(osv.Model): smtp_server_obj.send_email(cr, uid, msg) return True - def message_partner_by_email(self, cr, uid, email, context=None): + def message_partner_by_email(self, cr, uid, email, context = None): """Attempts to return the id of a partner address matching the given ``email``, and the corresponding partner id. Can be used by classes using the ``mail.thread`` mixin @@ -811,16 +814,16 @@ class mail_thread(osv.Model): # Note specific #------------------------------------------------------ - def log(self, cr, uid, id, message, secondary=False, context=None): + def log(self, cr, uid, id, message, secondary = False, context = None): _logger.warning("log() is deprecated. As this module inherit from \ mail.thread, the message will be managed by this \ module instead of by the res.log mechanism. Please \ use the mail.thread OpenChatter API instead of the \ now deprecated res.log.") - self.message_append_note(cr, uid, [id], 'res.log', message, context=context) + self.message_append_note(cr, uid, [id], 'res.log', message, context = context) - def message_append_note(self, cr, uid, ids, subject=None, body=None, parent_id=False, - type='notification', content_subtype='html', context=None): + def message_append_note(self, cr, uid, ids, subject = None, body = None, parent_id = False, + type = 'notification', subtype_id = False, content_subtype = 'html', context = None): if content_subtype == 'html': body_html = body body_text = body @@ -828,14 +831,14 @@ class mail_thread(osv.Model): body_html = body body_text = body return self.message_append(cr, uid, ids, subject, body_html, body_text, - type, parent_id=parent_id, - content_subtype=content_subtype, context=context) + type, subtype_id = subtype_id, parent_id = parent_id, + content_subtype = content_subtype, context = context) #------------------------------------------------------ # Subscription mechanism #------------------------------------------------------ - def message_get_subscribers(self, cr, uid, ids, context=None): + def message_get_subscribers(self, cr, uid, ids, context = None): """ Returns the current document followers. Basically this method checks in mail.subscription for entries with matching res_model, res_id. @@ -844,18 +847,18 @@ class mail_thread(osv.Model): ids returned by this method. """ subscr_obj = self.pool.get('mail.subscription') - subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - return [sub['user_id'][0] for sub in subscr_obj.read(cr, uid, subscr_ids, ['user_id'], context=context)] + subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context = context) + return [sub['user_id'][0] for sub in subscr_obj.read(cr, uid, subscr_ids, ['user_id'], context = context)] - def message_read_subscribers(self, cr, uid, ids, fields=['id', 'name', 'avatar'], context=None): + def message_read_subscribers(self, cr, uid, ids, fields = ['id', 'name', 'avatar'], context = None): """ Returns the current document followers as a read result. Used mainly for Chatter having only one method to call to have details about users. """ - user_ids = self.message_get_subscribers(cr, uid, ids, context=context) - return self.pool.get('res.users').read(cr, uid, user_ids, fields=fields, context=context) + user_ids = self.message_get_subscribers(cr, uid, ids, context = context) + return self.pool.get('res.users').read(cr, uid, user_ids, fields = fields, context = context) - def message_is_subscriber(self, cr, uid, ids, user_id = None, context=None): + def message_is_subscriber(self, cr, uid, ids, user_id = None, context = None): """ Check if uid or user_id (if set) is a subscriber to the current document. @@ -863,16 +866,17 @@ class mail_thread(osv.Model): check is done on uid """ sub_user_id = uid if user_id is None else user_id - if sub_user_id in self.message_get_subscribers(cr, uid, ids, context=context): + if sub_user_id in self.message_get_subscribers(cr, uid, ids, context = context): return True return False - def message_subscribe(self, cr, uid, ids, user_ids = None, context=None): + def message_subscribe(self, cr, uid, ids, user_ids = None, subtype_ids = None, context = None): """ Subscribe the user (or user_ids) to the current document. :param user_ids: a list of user_ids; if not set, subscribe uid instead """ + # TODO:Update Massage Subscribe and add paramenter subtype_ids # if subtype_ids is False: add default ones (res_model = self._name, default = True) # in method: if user_id already subscriber, update its subscription with subtype_ids @@ -881,14 +885,20 @@ class mail_thread(osv.Model): to_subscribe_uids = [uid] if user_ids is None else user_ids create_ids = [] for id in ids: - already_subscribed_user_ids = self.message_get_subscribers(cr, uid, [id], context=context) + already_subscribed_user_ids = self.message_get_subscribers(cr, uid, [id], context = context) for user_id in to_subscribe_uids: - if user_id in already_subscribed_user_ids: continue - create_ids.append(subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context)) + res = {'res_model': self._name, 'res_id': id, 'user_id': user_id} + res['subtype_ids'] = [0, 0, {'res_model': self._name, 'default': True}] + if user_id in already_subscribed_user_ids: + if subtype_ids: + res['subtype_ids'] = [(6, 0, subtype_ids)] + else: continue + create_ids.append(subscription_obj.create(cr, uid, res, context = context)) return create_ids + #TODO : Add method : add message_subscribe_udpate_subtypes(..., user_id, subtype_ids): - def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None): + def message_unsubscribe(self, cr, uid, ids, user_ids = None, context = None): """ Unsubscribe the user (or user_ids) from the current document. :param user_ids: a list of user_ids; if not set, subscribe @@ -900,17 +910,19 @@ class mail_thread(osv.Model): to_unsubscribe_uids = [uid] if user_ids is None else user_ids subscription_obj = self.pool.get('mail.subscription') to_delete_sub_ids = subscription_obj.search(cr, uid, - ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', 'in', to_unsubscribe_uids)], context=context) + ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', 'in', to_unsubscribe_uids)], context = context) if not to_delete_sub_ids: return False - return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context=context) + + return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context = context) #TODO : Add Method : add message_subscribeption_remove_subtype(..., user_id, subtype_id): #TODO : Add method : add message_subscription_remove_subtype_name(.., user_id, subtype_name) + #------------------------------------------------------ # Notification API #------------------------------------------------------ - def message_create_notify_by_email(self, cr, uid, new_msg_values, user_to_notify_ids, context=None): + def message_create_notify_by_email(self, cr, uid, new_msg_values, user_to_notify_ids, context = None): """ When creating a new message and pushing notifications, emails must be send if users have chosen to receive notifications by email via the notification_email_pref field. @@ -937,11 +949,11 @@ class mail_thread(osv.Model): user_to_notify_ids.remove(new_msg_values.get('user_id')) # get user_ids directly asked - user_to_push_from_parse_ids = self.message_parse_users(cr, uid, body, context=context) + user_to_push_from_parse_ids = self.message_parse_users(cr, uid, body, context = context) # try to find an email_to email_to = '' - for user in res_users_obj.browse(cr, uid, user_to_notify_ids, context=context): + for user in res_users_obj.browse(cr, uid, user_to_notify_ids, context = context): if not user.notification_email_pref == 'all' and \ not (user.notification_email_pref == 'to_me' and user.id in user_to_push_from_parse_ids): continue @@ -955,17 +967,17 @@ class mail_thread(osv.Model): return # try to find an email_from - current_user = res_users_obj.browse(cr, uid, [uid], context=context)[0] + current_user = res_users_obj.browse(cr, uid, [uid], context = context)[0] email_from = new_msg_values.get('email_from') if not email_from: email_from = current_user.user_email # get email content, create it (with mail_message.create) email_values = self.message_create_notify_get_email_dict(cr, uid, new_msg_values, email_from, email_to, context) - email_id = message_obj.create(cr, uid, email_values, context=context) + email_id = message_obj.create(cr, uid, email_values, context = context) return email_id - def message_create_notify_get_email_dict(self, cr, uid, new_msg_values, email_from, email_to, context=None): + def message_create_notify_get_email_dict(self, cr, uid, new_msg_values, email_from, email_to, context = None): values = dict(new_msg_values) body_html = new_msg_values.get('body_html', '') @@ -989,47 +1001,62 @@ class mail_thread(osv.Model): }) return values - def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs=True, context=None): + def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs = True, context = None): notif_obj = self.pool.get('mail.notification') msg_obj = self.pool.get('mail.message') if remove_childs: - notif_msg_ids = msg_obj.search(cr, uid, [('id', 'child_of', msg_ids)], context=context) + notif_msg_ids = msg_obj.search(cr, uid, [('id', 'child_of', msg_ids)], context = context) else: notif_msg_ids = msg_ids - to_del_notif_ids = notif_obj.search(cr, uid, ['&', ('user_id', '=', uid), ('message_id', 'in', notif_msg_ids)], context=context) - return notif_obj.unlink(cr, uid, to_del_notif_ids, context=context) + to_del_notif_ids = notif_obj.search(cr, uid, ['&', ('user_id', '=', uid), ('message_id', 'in', notif_msg_ids)], context = context) + return notif_obj.unlink(cr, uid, to_del_notif_ids, context = context) #------------------------------------------------------ # Thread_state #------------------------------------------------------ - def message_create_set_unread(self, cr, uid, ids, context=None): + def message_create_set_unread(self, cr, uid, ids, context = None): """ When creating a new message, set as unread if uid is not the object responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if obj.message_state and hasattr(obj, 'user_id') and (not obj.user_id or obj.user_id.id != uid): - self.message_mark_as_unread(cr, uid, [obj.id], context=context) + self.message_mark_as_unread(cr, uid, [obj.id], context = context) - def message_check_and_set_unread(self, cr, uid, ids, context=None): + def message_check_and_set_unread(self, cr, uid, ids, context = None): """ Set unread if uid is the object responsible or if the object has no responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if obj.message_state and hasattr(obj, 'user_id') and (not obj.user_id or obj.user_id.id == uid): - self.message_mark_as_unread(cr, uid, [obj.id], context=context) + self.message_mark_as_unread(cr, uid, [obj.id], context = context) - def message_mark_as_unread(self, cr, uid, ids, context=None): + def message_mark_as_unread(self, cr, uid, ids, context = None): """ Set as unread. """ - return self.write(cr, uid, ids, {'message_state': False}, context=context) + return self.write(cr, uid, ids, {'message_state': False}, context = context) - def message_check_and_set_read(self, cr, uid, ids, context=None): + def message_check_and_set_read(self, cr, uid, ids, context = None): """ Set read if uid is the object responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if not obj.message_state and hasattr(obj, 'user_id') and obj.user_id and obj.user_id.id == uid: - self.message_mark_as_read(cr, uid, [obj.id], context=context) + self.message_mark_as_read(cr, uid, [obj.id], context = context) - def message_mark_as_read(self, cr, uid, ids, context=None): + def message_mark_as_read(self, cr, uid, ids, context = None): """ Set as read. """ - return self.write(cr, uid, ids, {'message_state': True}, context=context) - + return self.write(cr, uid, ids, {'message_state': True}, context = context) + def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids): + subscription_obj = self.pool.get('mail.subscription') + subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [6, 0 , subtype_ids]}, context = context) #overright or add new one + + def message_subscription_remove_subtype(self, cr, uid, ids, user_id, subtype_id): + subscription_obj = self.pool.get('mail.subscription') + subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove linl or record ? + + def message_subscription_remove_subtype_name(self, cr, uid, ids, user_id, subtype_name): + subtype_obj = self.pool.get('mail.message.subtype') + subtype_ids = subtype_obj.search(cr, uid, [('name', '=', subtype_name), ('model_ids', '=', self._name)]) + if not subtype_ids: + return False + self.message_subscription_remove_subtype(cr, uid, ids, user_id, subtype_ids) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From b942c562240d999c2f20ea154547ac46dde179a8 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 9 Aug 2012 14:52:56 +0530 Subject: [PATCH 078/726] [ADD] Add demo data in crm lead bzr revid: fka@tinyerp.com-20120809092256-r27t6y9nvndwnole --- addons/crm/crm_lead.py | 17 ++++++++++------- addons/crm/crm_lead_demo.xml | 32 ++++++++++++++++++++++++++++++++ addons/mail/mail_thread.py | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index d5ec1309baa..675f41c94f4 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -275,6 +275,9 @@ class crm_lead(base_stage, osv.osv): def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) + obj = self.browse(cr, uid, obj_id, context) + if obj.user_id: + self.message_subscribe(cr, uid, ids, obj.user_id.id, context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id @@ -849,13 +852,13 @@ class crm_lead(base_stage, osv.osv): # OpenChatter methods and notifications # ---------------------------------------- - def message_get_subscribers(self, cr, uid, ids, context=None): - """ Override to add the salesman. """ - user_ids = super(crm_lead, self).message_get_subscribers(cr, uid, ids, context=context) - for obj in self.browse(cr, uid, ids, context=context): - if obj.user_id and not obj.user_id.id in user_ids: - user_ids.append(obj.user_id.id) - return user_ids + #def message_get_subscribers(self, cr, uid, ids, context=None): + #""" Override to add the salesman. """ + #user_ids = super(crm_lead, self).message_get_subscribers(cr, uid, ids, context=context) + #for obj in self.browse(cr, uid, ids, context=context): + #if obj.user_id and not obj.user_id.id in user_ids: + #user_ids.append(obj.user_id.id) + #return user_ids def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml index 7ed3bc2a86b..b064a9adfb1 100644 --- a/addons/crm/crm_lead_demo.xml +++ b/addons/crm/crm_lead_demo.xml @@ -540,5 +540,37 @@ ref('crm_case_ericdubois4'), ref('crm_case_abcfuelcounits0')], {}" /> + + new + + + + + won + + + + lost + + + + stage change + + + + + other + + + + + email + + + + comment + + + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 3e5bfabe350..21d123ec024 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1051,7 +1051,7 @@ class mail_thread(osv.Model): def message_subscription_remove_subtype(self, cr, uid, ids, user_id, subtype_id): subscription_obj = self.pool.get('mail.subscription') subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) - return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove linl or record ? + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove link def message_subscription_remove_subtype_name(self, cr, uid, ids, user_id, subtype_name): subtype_obj = self.pool.get('mail.message.subtype') From dae19bc174b3962088bf4b9fd0701f80ab8f8e5e Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 9 Aug 2012 16:48:06 +0530 Subject: [PATCH 079/726] [IMP] improve crm_lead bzr revid: fka@tinyerp.com-20120809111806-k79sserip4oyzo1r --- addons/crm/crm_lead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 675f41c94f4..a3fccffb011 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -277,7 +277,7 @@ class crm_lead(base_stage, osv.osv): obj_id = super(crm_lead, self).create(cr, uid, vals, context) obj = self.browse(cr, uid, obj_id, context) if obj.user_id: - self.message_subscribe(cr, uid, ids, obj.user_id.id, context = context) + self.message_subscribe(cr, uid, [obj_id], [obj.user_id.id], context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id From 2b331ed5e35640a23e8417bbf24d20b9746e3c13 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Mon, 13 Aug 2012 16:37:46 +0530 Subject: [PATCH 080/726] [IMP]all followers of the task project are automatically followers of the task bzr revid: sgo@tinyerp.com-20120813110746-wqivckynrcqnf7y6 --- addons/project/project.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/project/project.py b/addons/project/project.py index 6f3b23f4746..879e9500874 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -1209,6 +1209,9 @@ class task(base_stage, osv.osv): user_ids.append(obj.user_id.id) if obj.manager_id and not obj.manager_id.id in user_ids: user_ids.append(obj.manager_id.id) + if obj.project_id.followers: + for follower in obj.project_id.followers: + user_ids.append(follower.id) return user_ids def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): From 0e916d159242e46d3f4b2c914c0d8dc49e88ee03 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 13 Aug 2012 18:40:40 +0530 Subject: [PATCH 081/726] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120813131040-32v2tcz3eltkx4fn --- addons/crm/crm_lead.py | 28 +++++++++++++++++++++------- addons/mail/mail_thread.py | 3 ++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index da845cc8e5f..b02369cce9f 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,7 +865,9 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_stage_change') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id=res_id,context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -875,33 +877,45 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_append_note(cr, uid, [id], body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_new') + res_id = res[1] + self.message_append_note(cr, uid, [id], body=message, subtype_id=res_id, context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_lost') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message,subtype_id=res_id, context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_won') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] if action == 'log': prefix = 'Logged' else: prefix = 'Scheduled' message = _("%s a call for the %s.") % (prefix, phonecall.date) - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) def _lead_set_partner_send_note(self, cr, uid, ids, context=None): for lead in self.browse(cr, uid, ids, context=context): message = _("%s partner is now set to %s." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name)) - lead.message_append_note(body=message) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + lead.message_append_note(body=message, subtype_id=res_id) return True def convert_opportunity_send_note(self, cr, uid, lead, context=None): message = _("Lead has been converted to an opportunity.") - lead.message_append_note(body=message) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + lead.message_append_note(body=message, subtype_id=res_id) return True crm_lead() diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 79b734379d0..14e9138be55 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -335,6 +335,7 @@ class mail_thread(osv.Model): 'parent_id': parent_id, 'date': email_date or fields.datetime.now(), 'type': type, + 'subtype_id' : subtype_id, 'content_subtype': content_subtype, 'state': state, 'message_id': message_id, @@ -866,7 +867,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id=None, body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype_id=False, body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body From 9fac5651d55d44e4b6eb8d16fe0b802bc1df349d Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 12:21:49 +0530 Subject: [PATCH 082/726] [IMP] improve as per suggetion bzr revid: fka@tinyerp.com-20120814065149-h1xf3we6t37bsyk3 --- addons/crm/crm_data.xml | 2 +- addons/crm/crm_lead.py | 28 +++++++--------------------- addons/mail/data/mail_group_data.xml | 2 +- addons/mail/mail_thread.py | 13 ++++++------- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml index 5e5f408673a..dfe2e4653c3 100644 --- a/addons/crm/crm_data.xml +++ b/addons/crm/crm_data.xml @@ -63,7 +63,7 @@ - + Module CRM has been installed From the top menu Sales, you can: trace leads and opportunities, get accurate forecast on your sales pipeline, plan meetings and phonecalls, get realtime statistics and efficiently organize the communication with your prospects. diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index b02369cce9f..976eb333ddd 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,9 +865,7 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_stage_change') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id=res_id,context=context) + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id="stage change",context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -877,45 +875,33 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_new') - res_id = res[1] - self.message_append_note(cr, uid, [id], body=message, subtype_id=res_id, context=context) + self.message_append_note(cr, uid, [id], body=message, subtype_id="new", context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_lost') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message,subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message,subtype_id="lost", context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_won') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message, subtype_id="won", context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] if action == 'log': prefix = 'Logged' else: prefix = 'Scheduled' message = _("%s a call for the %s.") % (prefix, phonecall.date) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message, context=context) def _lead_set_partner_send_note(self, cr, uid, ids, context=None): for lead in self.browse(cr, uid, ids, context=context): message = _("%s partner is now set to %s." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name)) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - lead.message_append_note(body=message, subtype_id=res_id) + lead.message_append_note(body=message) return True def convert_opportunity_send_note(self, cr, uid, lead, context=None): message = _("Lead has been converted to an opportunity.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - lead.message_append_note(body=message, subtype_id=res_id) + lead.message_append_note(body=message) return True crm_lead() diff --git a/addons/mail/data/mail_group_data.xml b/addons/mail/data/mail_group_data.xml index 09a6ca29a2d..3a2ad01fab8 100644 --- a/addons/mail/data/mail_group_data.xml +++ b/addons/mail/data/mail_group_data.xml @@ -16,7 +16,7 @@ - + Welcome to OpenERP! Your homepage is a summary of messages you received and key information about documents you follow. diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 14e9138be55..8d1259ea4ff 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -228,8 +228,8 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, - type = 'email', subtype_id = False, email_date = None, parent_id = False, + def message_append(self, cr, uid, threads, subject,subtype_id = "other", body_text=None, body_html=None, + type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, email_cc=None, email_bcc=None, reply_to=None, @@ -335,7 +335,6 @@ class mail_thread(osv.Model): 'parent_id': parent_id, 'date': email_date or fields.datetime.now(), 'type': type, - 'subtype_id' : subtype_id, 'content_subtype': content_subtype, 'state': state, 'message_id': message_id, @@ -383,11 +382,11 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), + subtype_id = msg_dict.get('subtype_id','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), type = msg_dict.get('type', 'email'), - subtype_id = msg_dict.get('subtype_id', False), content_subtype = msg_dict.get('content_subtype'), state = msg_dict.get('state'), partner_ids = msg_dict.get('partner_ids'), @@ -867,7 +866,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id=False, body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype_id='other', body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body @@ -875,8 +874,8 @@ class mail_thread(osv.Model): else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject, body_html, body_text, - type, subtype_id = subtype_id, parent_id = parent_id, + return self.message_append(cr, uid, ids, subject,subtype_id, body_html, body_text, + type, parent_id = parent_id, content_subtype=content_subtype, context=context) #------------------------------------------------------ From 86768264f4e0027d62ac300410a8ef691e95d862 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 12:49:19 +0530 Subject: [PATCH 083/726] [IMP] Add constraints in message subtype model bzr revid: fka@tinyerp.com-20120814071919-pk9wkepp7v1geswa --- addons/mail/mail_message_subtype.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py index 0a167a0f1d9..0c4f5e7baa6 100644 --- a/addons/mail/mail_message_subtype.py +++ b/addons/mail/mail_message_subtype.py @@ -39,3 +39,6 @@ class mail_message_subtype(osv.osv): _defaults = { 'default': True, } + _sql_constraints = [ + ('name_uniq', 'unique (name)', 'The name of the message subtype must be unique !') + ] From b4b9ce7178494a5b414995d6236b255cc396caa2 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Tue, 14 Aug 2012 15:42:12 +0530 Subject: [PATCH 084/726] [IMP]improve code bzr revid: sgo@tinyerp.com-20120814101212-rjmlbtpmhdviick7 --- addons/project/project.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index 879e9500874..f7309716429 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -1209,9 +1209,10 @@ class task(base_stage, osv.osv): user_ids.append(obj.user_id.id) if obj.manager_id and not obj.manager_id.id in user_ids: user_ids.append(obj.manager_id.id) - if obj.project_id.followers: - for follower in obj.project_id.followers: - user_ids.append(follower.id) + if obj.project_id: + subscriber_ids = self.pool.get('project.project').message_get_subscribers(cr, uid, [obj.project_id.id], context=context) + for user_id in subscriber_ids: + user_ids.append(user_id) return user_ids def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): From 0ae13ed393ed42b1d6d3ef600556d526e7840a9d Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 17:42:50 +0530 Subject: [PATCH 085/726] [IMP] improve message_create() in mail_thread bzr revid: fka@tinyerp.com-20120814121250-32fb4key3nt9lcaq --- addons/crm/crm_lead.py | 8 +++--- addons/mail/mail_thread.py | 55 ++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 976eb333ddd..0ec901698df 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,7 +865,7 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id="stage change",context=context) + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change",context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -875,16 +875,16 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_append_note(cr, uid, [id], body=message, subtype_id="new", context=context) + self.message_append_note(cr, uid, [id], body=message, subtype="new", context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - return self.message_append_note(cr, uid, ids, body=message,subtype_id="lost", context=context) + return self.message_append_note(cr, uid, ids, body=message,subtype="lost", context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - return self.message_append_note(cr, uid, ids, body=message, subtype_id="won", context=context) + return self.message_append_note(cr, uid, ids, body=message, subtype="won", context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 8d1259ea4ff..4ffdac80116 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -153,29 +153,37 @@ class mail_thread(osv.Model): notification_obj = self.pool.get('mail.notification') body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') + subtype_obj=self.pool.get('mail.message.subtype') + subtype_id=subtype_obj.search(cr, uid, [('name', '=', vals.get('subtype')), ('model_ids', '=', self._name)]) + vals['subtype_id'] = subtype_id[0] + user_subscribe=self.message_is_subscriber(cr, uid, [thread_id], vals['user_id'], context) # automatically subscribe the writer of the message if vals['user_id']: self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) - # create message - msg_id = message_obj.create(cr, uid, vals, context=context) - - # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) - - # special: if install mode, do not push demo data - if context.get('install_mode', False): - return msg_id - - # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) - for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) - - # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) - - return msg_id + for subtype_obj in subtype_obj.browse(cr,uid,subtype_id,context): + if subtype_obj.default and user_subscribe: + # create message + msg_id = message_obj.create(cr, uid, vals, context=context) + + # Set as unread if writer is not the document responsible + self.message_create_set_unread(cr, uid, [thread_id], context=context) + + # special: if install mode, do not push demo data + if context.get('install_mode', False): + return msg_id + + # get users that will get a notification pushed + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) + for id in user_to_push_ids: + notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) + + # create the email to send + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) + + return msg_id + else: + return False def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -228,7 +236,7 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject,subtype_id = "other", body_text=None, body_html=None, + def message_append(self, cr, uid, threads, subject,subtype = "other", body_text=None, body_html=None, type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, @@ -330,6 +338,7 @@ class mail_thread(osv.Model): data = { 'subject': subject, + 'subtype': subtype, 'body_text': body_text or (hasattr(thread, 'description') and thread.description or ''), 'body_html': body_html or '', 'parent_id': parent_id, @@ -382,7 +391,7 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), - subtype_id = msg_dict.get('subtype_id','other'), + subtype = msg_dict.get('subtype','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), @@ -866,7 +875,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id='other', body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype='other', body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body @@ -874,7 +883,7 @@ class mail_thread(osv.Model): else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject,subtype_id, body_html, body_text, + return self.message_append(cr, uid, ids, subject,subtype, body_html, body_text, type, parent_id = parent_id, content_subtype=content_subtype, context=context) From f1dd8b488d68fa5fc95fb77d935739ed5953d0ba Mon Sep 17 00:00:00 2001 From: Vishmita Date: Tue, 14 Aug 2012 17:58:01 +0530 Subject: [PATCH 086/726] [Fix]column name in tree view can't get value of String attribute. bzr revid: vja@tinyerp.com-20120814122801-mspq40qkjh5f6x20 --- addons/web/static/src/xml/base.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 0eddd914f01..0fc022f15c8 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -599,7 +599,7 @@ From 40768f8fd838635737dc7a376a7282a49620d43e Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 19:13:14 +0530 Subject: [PATCH 087/726] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120814134314-lyen3a13a76db9sv --- addons/mail/mail_thread.py | 74 +++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 04cb5bc6bc6..5b2efb98fcc 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -140,7 +140,7 @@ class mail_thread(osv.Model): # mail.message wrappers and tools #------------------------------------------------------ - def message_create(self, cr, uid, thread_id, vals, context=None): + def message_create(self, cr, uid, thread_id, vals, context = None): """ OpenChatter: wrapper of mail.message create method - creates the mail.message - automatically subscribe the message writer @@ -151,40 +151,40 @@ class mail_thread(osv.Model): message_obj = self.pool.get('mail.message') notification_obj = self.pool.get('mail.notification') + subscription_obj = self.pool.get('mail.subscription') body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') - subtype_obj=self.pool.get('mail.message.subtype') - subtype_id=subtype_obj.search(cr, uid, [('name', '=', vals.get('subtype')), ('model_ids', '=', self._name)]) - if subtype_id: - vals['subtype_id'] = subtype_id[0] - user_subscribe=self.message_is_subscriber(cr, uid, [thread_id], vals['user_id'], context) # automatically subscribe the writer of the message if vals['user_id']: - self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) + self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context = context) - for subtype_obj in subtype_obj.browse(cr,uid,subtype_id,context): - if subtype_obj.default and user_subscribe: - # create message - msg_id = message_obj.create(cr, uid, vals, context=context) - - # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) - - # special: if install mode, do not push demo data - if context.get('install_mode', False): - return msg_id - - # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) - for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) - - # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) - - return msg_id - else: - return False + # create message + msg_id = message_obj.create(cr, uid, vals, context = context) + + # Set as unread if writer is not the document responsible + self.message_create_set_unread(cr, uid, [thread_id], context = context) + + # special: if install mode, do not push demo data + if context.get('install_mode', False): + return msg_id + + # get users that will get a notification pushed + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context = context) + subtype_id = vals.get('subtype', False) + subtype_ids = self.pool.get('mail.message.subtype').name_search(cr, uid, subtype_id) + subtype_id = len(subtype_ids) and subtype_ids[0][0] or False + for user_id in user_to_push_ids: + if subtype_id: + #TOCHECK: domain to find subscrition details of subtype + subscription_ids = subscription_obj.search(cr, uid, [('res_model','=',vals['model']),('res_id','=',vals['res_id']),('subtype_ids','in',subtype_id),('user_id','=',user_id)]) + if not subscription_ids: + continue + notification_obj.create(cr, uid, {'user_id': user_id, 'message_id': msg_id}, context = context) + + # create the email to send + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context = context) + + return msg_id def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -237,13 +237,13 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject,subtype = "other", body_text=None, body_html=None, + def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, email_cc=None, email_bcc=None, reply_to=None, headers=None, message_id=False, references=None, - attachments=None, original=None, context=None): + attachments=None, original=None, subtype = "other", context=None): """ Creates a new mail.message through message_create. The new message is attached to the current mail.thread, containing all the details passed as parameters. All attachments will be attached to the @@ -392,7 +392,6 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), - subtype = msg_dict.get('subtype','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), @@ -412,6 +411,7 @@ class mail_thread(osv.Model): attachments = msg_dict.get('attachments'), headers = msg_dict.get('headers'), original = msg_dict.get('original'), + subtype = msg_dict.get('subtype','other'), context = context) #------------------------------------------------------ @@ -876,17 +876,17 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype='other', body=None, parent_id=False, - type='notification', content_subtype='html', context=None): + def message_append_note(self, cr, uid, ids, subject=None, body=None, parent_id=False, + type='notification', content_subtype='html', subtype='other', context=None): if content_subtype == 'html': body_html = body body_text = body else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject,subtype, body_html, body_text, + return self.message_append(cr, uid, ids, subject, body_text, body_html, type, parent_id = parent_id, - content_subtype=content_subtype, context=context) + content_subtype=content_subtype, subtype=subtype, context=context) #------------------------------------------------------ # Subscription mechanism From 95082105eba58087a461ed3af51e4302c3d7af78 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 16 Aug 2012 13:00:21 +0530 Subject: [PATCH 088/726] [IMP]improve code as per new changes bzr revid: sgo@tinyerp.com-20120816073021-p7wwjuoeegapjxjn --- addons/project/project.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/project/project.py b/addons/project/project.py index 1a8f8c8bfe5..c4b0472f5a1 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -1122,6 +1122,10 @@ class task(base_stage, osv.osv): task_id = super(task, self).create(cr, uid, vals, context=context) self._store_history(cr, uid, [task_id], context=context) self.create_send_note(cr, uid, [task_id], context=context) + task_obj = self.browse(cr, uid, task_id, context=context) + if task_obj.project_id: + project_follower_ids = [follow.id for follow in task_obj.project_id.message_follower_ids] + self.message_subscribe(cr, uid, [task_id], project_follower_ids, context=context) return task_id # Overridden to reset the kanban_state to normal whenever From 1f60976cbc94ce1ad1500be21a7b98fdafbed0a7 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 16 Aug 2012 14:16:21 +0530 Subject: [PATCH 089/726] [IMP]minor changes in name bzr revid: sgo@tinyerp.com-20120816084621-s0v4o24o6hlqfrs0 --- addons/project/project.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index c4b0472f5a1..2815ec0f3ca 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -1122,9 +1122,9 @@ class task(base_stage, osv.osv): task_id = super(task, self).create(cr, uid, vals, context=context) self._store_history(cr, uid, [task_id], context=context) self.create_send_note(cr, uid, [task_id], context=context) - task_obj = self.browse(cr, uid, task_id, context=context) - if task_obj.project_id: - project_follower_ids = [follow.id for follow in task_obj.project_id.message_follower_ids] + task_record = self.browse(cr, uid, task_id, context=context) + if task_record.project_id: + project_follower_ids = [follower.id for follower in task_record.project_id.message_follower_ids] self.message_subscribe(cr, uid, [task_id], project_follower_ids, context=context) return task_id From 64470badab104a2b934af0f7c64223e4f2baa439 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 16 Aug 2012 15:08:17 +0530 Subject: [PATCH 090/726] [IMP]:project:improved code bzr revid: apa@tinyerp.com-20120816093817-gxsvt8bdmjvb2bu8 --- addons/project/project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index 2815ec0f3ca..55dfd305189 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -1120,12 +1120,12 @@ class task(base_stage, osv.osv): def create(self, cr, uid, vals, context=None): task_id = super(task, self).create(cr, uid, vals, context=context) - self._store_history(cr, uid, [task_id], context=context) - self.create_send_note(cr, uid, [task_id], context=context) task_record = self.browse(cr, uid, task_id, context=context) if task_record.project_id: project_follower_ids = [follower.id for follower in task_record.project_id.message_follower_ids] self.message_subscribe(cr, uid, [task_id], project_follower_ids, context=context) + self._store_history(cr, uid, [task_id], context=context) + self.create_send_note(cr, uid, [task_id], context=context) return task_id # Overridden to reset the kanban_state to normal whenever From a929752e463204cd1b9c3c214edc25d6d6897d09 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 16 Aug 2012 16:33:06 +0530 Subject: [PATCH 091/726] [IMP]remove selectin subtype field & change name of obj bzr revid: fka@tinyerp.com-20120816110306-q0mrqa2tp8128nmv --- addons/crm/crm_lead.py | 6 +++--- addons/mail/mail_message.py | 2 +- addons/mail/mail_thread.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 2e6a3b5514d..0ecc7d9bee2 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -278,9 +278,9 @@ class crm_lead(base_stage, osv.osv): def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) - obj = self.browse(cr, uid, obj_id, context) - if obj.user_id: - self.message_subscribe(cr, uid, [obj_id], [obj.user_id.id], context = context) + record = self.browse(cr, uid, obj_id, context) + if record.user_id: + self.message_subscribe(cr, uid, [obj_id], [record.user_id.id], context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 3d0ea943d3a..a50d091f7ff 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -234,7 +234,7 @@ class mail_message(osv.Model): select=True, ondelete='set null', help="Parent message, used for displaying as threads with hierarchy"), 'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'), - 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype', select = True), + 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'), } _defaults = { diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 840cfbaaa37..ddace0cf9b9 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -273,7 +273,7 @@ class mail_thread(osv.Model): followers_obj = self.pool.get('mail.followers') subtype_obj = self.pool.get('mail.message.subtype') subtype_name = vals.get('subtype') - sutype = False + subtype = False body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') if subtype_name: subtypes = subtype_obj.name_search(cr, uid, subtype_name) From 1b2f6c7551ffeda6c17c7d9492aae08d85efe6e3 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 20 Aug 2012 10:42:22 +0530 Subject: [PATCH 092/726] [IMP]add message_subtype.yml bzr revid: rma@tinyerp.com-20120820051222-9dk4p47uz53j5nzo --- addons/crm/__openerp__.py | 3 +- .../crm/test/process/crm_message_subtype.yml | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 addons/crm/test/process/crm_message_subtype.yml diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 643908c1098..f0f181c47da 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -129,7 +129,8 @@ Creates a dashboard for CRM that includes: 'test/process/segmentation.yml', 'test/ui/crm_demo.yml', 'test/ui/duplicate_lead.yml', - 'test/ui/delete_lead.yml' + 'test/ui/delete_lead.yml', + 'test/process/crm_message_subtype.yml', ], 'installable': True, 'application': True, diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml new file mode 100644 index 00000000000..a83c729ecd4 --- /dev/null +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -0,0 +1,54 @@ +- + I have add the sub_type name other with default false +- + !record {model: mail.message.subtype, id: mail_subtype_lead_won }: + name: won + model_ids: + - crm.model_crm_lead + default: False +- + I have add the sub_type name email with default true +- + !record {model: mail.message.subtype, id: mail_subtype_lead_email }: + name: email + model_ids: + - crm.model_crm_lead + default: True +- + I have add the sub_type name comment with default true +- + !record {model: mail.message.subtype, id: mail_subtype_lead_comment }: + name: comment + model_ids: + - crm.model_crm_lead + default: True + +- + I have search and write its subtype in followers +- + !python {model: mail.followers}: | + ids = self.search(cr, uid, [('res_model', '=', 'crm.lead'),('res_id', '=', ref('crm_case_1'))]) + self.write(cr, uid, ids, {'subtype_ids': [(6,0,[ref('mail_subtype_lead_won')])]}) +- + I have change the lead into mark won +- + !python {model: crm.lead}: | + self.convert_opportunity(cr, uid ,[ref("crm_case_1")], ref("base.res_partner_4")) + self.case_mark_won(cr, uid,[ref("crm_case_1")] ) +- + I have check the lead into mark won +- + !assert {model: crm.lead, id: crm_case_1 ,string: 'The record is not in won state'}: + - state == 'done' +- + I have check to if subtype is won then display notification. +- + !python {model: mail.message}: | + ids = self.search(cr, uid, [('model', '=','crm.lead'),('res_id', '=', ref('crm_case_1'))]) + browse = self.browse(cr,uid,ids) + + assert ids, 'lead is in won' + + + + From aef5236ba71e9150b56c6b74f4518d7362e6010b Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 20 Aug 2012 12:48:10 +0530 Subject: [PATCH 093/726] [FIX]make changes into crm_message_subtype.yml file bzr revid: rma@tinyerp.com-20120820071810-fn1wdg36syq1epd5 --- .../crm/test/process/crm_message_subtype.yml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index a83c729ecd4..705d3cc2fc4 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -22,9 +22,8 @@ model_ids: - crm.model_crm_lead default: True - - - I have search and write its subtype in followers + I have add the subtypes as won in feeds - !python {model: mail.followers}: | ids = self.search(cr, uid, [('res_model', '=', 'crm.lead'),('res_id', '=', ref('crm_case_1'))]) @@ -41,14 +40,9 @@ !assert {model: crm.lead, id: crm_case_1 ,string: 'The record is not in won state'}: - state == 'done' - - I have check to if subtype is won then display notification. + I have check the subtype as won in feeds - - !python {model: mail.message}: | - ids = self.search(cr, uid, [('model', '=','crm.lead'),('res_id', '=', ref('crm_case_1'))]) - browse = self.browse(cr,uid,ids) - - assert ids, 'lead is in won' - - - - + !python {model: mail.followers}: | + followers_ids =self.search(cr, uid, [('res_model', '=','crm.lead'),('res_id', '=', ref('crm_case_1')),('subtype_ids', 'in',[ref('mail_subtype_lead_won')])]) + if len(followers_ids): + assert followers_ids, 'lead is in won' From 82b2b3a626befc97c14591c80b4952c5eed99f6d Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Wed, 22 Aug 2012 11:57:22 +0530 Subject: [PATCH 094/726] [IMP]add name and checkbox on click of follow and make it work as add in subtype_ids in followers bzr revid: sgo@tinyerp.com-20120822062722-ru93dme523lnuko7 --- addons/mail/mail_thread.py | 6 ++-- addons/mail/static/src/js/mail_followers.js | 35 +++++++++++++++++-- addons/mail/static/src/xml/mail_followers.xml | 5 +++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index ddace0cf9b9..d552dc108a4 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1192,10 +1192,10 @@ class mail_thread(osv.Model): """ Set as read. """ return self.write(cr, uid, ids, {'message_state': True}, context=context) - def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids): + def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None): subscription_obj = self.pool.get('mail.followers') - subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) - return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [6, 0 , subtype_ids]}, context = context) #overright or add new one + subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids),('user_id','=',user_id)]) + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one def message_subscription_remove_subtype(self, cr, uid, ids, user_id, subtype_id): subscription_obj = self.pool.get('mail.followers') diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 0e920f73041..4e49919e7d2 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -31,6 +31,7 @@ openerp_mail_followers = function(session, mail) { this.params.display_control = this.node.attrs.display_control || false; this.params.display_actions = this.node.attrs.display_actions || false; this.ds_model = new session.web.DataSetSearch(this, this.view.model); + this.sub_model = new session.web.DataSetSearch(this,'mail.message.subtype') this.ds_follow = new session.web.DataSetSearch(this, this.field.relation); }, @@ -42,8 +43,21 @@ openerp_mail_followers = function(session, mail) { this._check_visibility(); this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); }); if (! this.params.display_control) { - this.$element.find('button.oe_mail_button_followers').hide(); } - this.$element.find('button.oe_mail_button_follow').click(function () { self.do_follow(); }) + this.$element.find('button.oe_mail_button_followers').hide(); + } + this.$element.find('ul.oe_mail_recthread_subtype').click(function () { + var sublist = new Array(); + _($(this).find('.oe_msg_subtype_check')).each(function (record){ + if($(record).is(':checked')) { + sublist.push(parseInt($(record).attr('id'))) + } + }); + self.ds_model.call('message_subscribe_udpate_subtypes',[[self.view.datarecord.id],self.session.uid,sublist]) + }) + this.$element.find('button.oe_mail_button_follow').click(function () { + self.add_subtype(); + self.do_follow(); + }) .mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) .mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); this.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); }) @@ -103,10 +117,25 @@ openerp_mail_followers = function(session, mail) { this.$element.find('button.oe_mail_button_follow').show(); this.$element.find('button.oe_mail_button_unfollow').hide(); } }, - + + subtype_value: function(value_) { + return this.sub_model.call('read', [value_ || this.get_value(),['name', 'default']]).then(this.proxy('read_subtype')); + }, + + read_subtype: function(records) { + this.reinit() + var subtype_list = this.$element.find('ul.oe_mail_recthread_subtype').empty(); + _(records).each(function (record) { + $(session.web.qweb.render('mail.subtype.ids', {'record': record})).appendTo(subtype_list); + }); + }, + do_follow: function () { return this.ds_model.call('message_subscribe', [[this.view.datarecord.id]]).pipe(this.proxy('set_value')); }, + add_subtype: function () { + return this.sub_model.call('search', [[['model_ids.model','=',this.view.model]]]).pipe(this.proxy('subtype_value')); + }, do_unfollow: function () { return this.ds_model.call('message_unsubscribe', [[this.view.datarecord.id]]).pipe(this.proxy('set_value')); diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index 53c899b9569..9979aa9d6fa 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -16,6 +16,7 @@

    +
      @@ -27,5 +28,9 @@ +
    • + + +
    • From ecdab52f06551bca82a53544c52194970779a4e1 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Wed, 22 Aug 2012 14:53:17 +0530 Subject: [PATCH 095/726] [IMP]if subtype selected its write in follower and improve code bzr revid: sgo@tinyerp.com-20120822092317-4nlhfton4ltk1lcq --- addons/mail/static/src/js/mail_followers.js | 29 ++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 4e49919e7d2..2940ae54288 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -33,6 +33,7 @@ openerp_mail_followers = function(session, mail) { this.ds_model = new session.web.DataSetSearch(this, this.view.model); this.sub_model = new session.web.DataSetSearch(this,'mail.message.subtype') this.ds_follow = new session.web.DataSetSearch(this, this.field.relation); + this.follow_model = new session.web.DataSetSearch(this,'mail.followers') }, start: function() { @@ -41,6 +42,8 @@ openerp_mail_followers = function(session, mail) { // any other method to know if the view is in create mode anymore this.view.on("change:actual_mode", this, this._check_visibility); this._check_visibility(); + self.add_subtype(); + this.$element.find('ul.oe_mail_recthread_subtype').hide() this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); }); if (! this.params.display_control) { this.$element.find('button.oe_mail_button_followers').hide(); @@ -55,12 +58,13 @@ openerp_mail_followers = function(session, mail) { self.ds_model.call('message_subscribe_udpate_subtypes',[[self.view.datarecord.id],self.session.uid,sublist]) }) this.$element.find('button.oe_mail_button_follow').click(function () { - self.add_subtype(); self.do_follow(); + self.$element.find('ul.oe_mail_recthread_subtype').show() }) .mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) .mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); - this.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); }) + this.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); + self.$element.find('ul.oe_mail_recthread_subtype').hide() }) .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); this.reinit(); @@ -81,6 +85,7 @@ openerp_mail_followers = function(session, mail) { this.$element.find('button.oe_mail_button_followers').html('Hide followers') this.$element.find('button.oe_mail_button_follow').hide(); this.$element.find('button.oe_mail_button_unfollow').hide(); + this.$element.find('ul.oe_mail_recthread_subtype').hide() }, set_value: function(value_) { @@ -112,10 +117,12 @@ openerp_mail_followers = function(session, mail) { }); if (this.is_subscriber) { this.$element.find('button.oe_mail_button_follow').hide(); - this.$element.find('button.oe_mail_button_unfollow').show(); } + this.$element.find('button.oe_mail_button_unfollow').show(); + this.$element.find('ul.oe_mail_recthread_subtype').show()} else { this.$element.find('button.oe_mail_button_follow').show(); - this.$element.find('button.oe_mail_button_unfollow').hide(); } + this.$element.find('button.oe_mail_button_unfollow').hide(); + this.$element.find('ul.oe_mail_recthread_subtype').hide() } }, subtype_value: function(value_) { @@ -123,9 +130,19 @@ openerp_mail_followers = function(session, mail) { }, read_subtype: function(records) { - this.reinit() + var self = this var subtype_list = this.$element.find('ul.oe_mail_recthread_subtype').empty(); - _(records).each(function (record) { + var follow_ids = this.follow_model.call('search',[[['res_model','=',this.ds_model.model],['res_id','=',this.view.datarecord.id],['user_id','=',this.session.uid]]]) + follow_ids.then(function (record){ + var msg_subtype = self.follow_model.call('read', [record,['subtype_ids']]); + if(msg_subtype){ + msg_subtype.then(function (subtype){ + _(subtype[0].subtype_ids).each(function (subtype_id){ + self.$element.find('.oe_msg_subtype_check[id=' + subtype_id + ']')[0].checked=true + }); + })} + }); + _(records).each(function (record) { $(session.web.qweb.render('mail.subtype.ids', {'record': record})).appendTo(subtype_list); }); }, From 642e4c02b1fa3685bb386b5821c4216e98681812 Mon Sep 17 00:00:00 2001 From: "Ravish Murari (OpenERP)" Date: Wed, 22 Aug 2012 15:41:34 +0530 Subject: [PATCH 096/726] [FIX] Owner's Equity Accounts should be under Liabilities lp bug: https://launchpad.net/bugs/1034279 fixed bzr revid: rmu@tinyerp.com-20120822101134-6ttkwofpnz0zdudj --- addons/l10n_in/l10n_in_private_chart.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/l10n_in/l10n_in_private_chart.xml b/addons/l10n_in/l10n_in_private_chart.xml index db11d0638c8..570adc183af 100644 --- a/addons/l10n_in/l10n_in_private_chart.xml +++ b/addons/l10n_in/l10n_in_private_chart.xml @@ -278,7 +278,7 @@ view - +
      @@ -27,7 +27,12 @@
    • -
    • + \ + +
    • ${inv.partner_id.title or ''|entity} ${inv.partner_id.name |entity}
      ${inv.partner_id.title and inv.partner_id.title.name or ''|entity} ${inv.partner_id.name |entity}
      ${inv.address_invoice_id.street or ''|entity}
      ${inv.address_invoice_id.street2 or ''|entity}
      ${inv.address_invoice_id.zip or ''|entity} ${inv.address_invoice_id.city or ''|entity}
      - +
      From 7efb26b94a4c2c9b3a4488320caffb132e9c3cd2 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 23 Aug 2012 16:44:11 +0530 Subject: [PATCH 106/726] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120823111411-18n8pdrbinevs0vc --- addons/audittrail/audittrail.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 549c84c7ded..6f76ea62429 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -434,7 +434,6 @@ class audittrail_objects_proxy(object_proxy): on specific fields only. :return: True """ - resource_pool = pool.get(model.model) # loop on all the given ids for res_id in res_ids: # compare old and new values and get audittrail log lines accordingly @@ -442,8 +441,7 @@ class audittrail_objects_proxy(object_proxy): # if at least one modification has been found for model_id, resource_id in lines: - res_name = resource_pool.browse(cr, uid, resource_id) - name = 'name' in res_name._columns.keys() and res_name.name or '' + name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1] vals = { 'method': method, 'object_id': model_id, From c5bc0ce1f31bdb21fff44a3452b5409dad4ae9cc Mon Sep 17 00:00:00 2001 From: "Ravish Murari (OpenERP)" Date: Thu, 23 Aug 2012 19:00:31 +0530 Subject: [PATCH 107/726] [FIX] improved the in code bzr revid: rmu@tinyerp.com-20120823133031-9atxtgh0d3pypus4 --- addons/account/account_move_line.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 8923f4b92f2..b97cdd12874 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1184,17 +1184,12 @@ class account_move_line(osv.osv): jour_period_obj = self.pool.get('account.journal.period') cr.execute('SELECT state FROM account_journal_period WHERE journal_id = %s AND period_id = %s', (journal_id, period_id)) result = cr.fetchall() + journal = journal_obj.browse(cr, uid, journal_id, context=context) + period = period_obj.browse(cr, uid, period_id, context=context) for (state,) in result: if state == 'done': - - journal = journal_obj.read(cr, uid, journal_id, ['name']) - period = period_obj.read(cr, uid, period_id, ['name']) - raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period['name'],journal['name']))) - raise osv.except_osv(_('Error!'), _('You cannot add/modify entries in a closed journal.')) - + raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period.name,journal.name))) if not result: - journal = journal_obj.browse(cr, uid, journal_id, context=context) - period = period_obj.browse(cr, uid, period_id, context=context) jour_period_obj.create(cr, uid, { 'name': (journal.code or journal.name)+':'+(period.name or ''), 'journal_id': journal.id, From cc56b498a14992e4fe78ec11962da1161466d726 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 24 Aug 2012 14:16:28 +0530 Subject: [PATCH 108/726] [IMP]if record is unread it also show only those record which checked in subtype bzr revid: sgo@tinyerp.com-20120824084628-r9bvejcya6mt6l33 --- addons/mail/mail_thread.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index c7f77208149..04a71a91a5b 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -319,9 +319,11 @@ class mail_thread(osv.Model): subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', thread_ids)], context=context) notif_user_ids = [] # check with subtype + is_subtype = False for subscription in subscr_obj.browse(cr, uid, subscr_ids, context=context): if subtype_id: if subtype_id in [subtype.id for subtype in subscription.subtype_ids]: + is_subtype = True notif_user_ids.append(subscription.user_id.id) else: notif_user_ids.append(subscription.user_id.id) @@ -330,7 +332,8 @@ class mail_thread(osv.Model): if hasattr(self, 'get_needaction_user_ids') and self._columns.get('user_id'): user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context=context) for id, user_ids in user_ids_dict.iteritems(): - notif_user_ids += user_ids + if is_subtype: + notif_user_ids += user_ids # add users notified of the parent messages (because: if parent message contains @login, login must receive the replies) if new_msg_vals.get('parent_id'): From 0516472570f6c1cb4b1d935e08f3cf436d812156 Mon Sep 17 00:00:00 2001 From: "Ravish Murari (OpenERP)" Date: Fri, 24 Aug 2012 17:34:25 +0530 Subject: [PATCH 109/726] [merge] change in code bzr revid: rmu@tinyerp.com-20120824120425-5v2nx6jt58ium1ee --- addons/procurement/procurement.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index d624f7dca6c..c4795959603 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -333,13 +333,8 @@ class procurement_order(osv.osv): move_obj = self.pool.get('stock.move') for procurement in self.browse(cr, uid, ids, context=context): if procurement.product_qty <= 0.00: - raise osv.except_osv(_('Data Insufficient !'), _('Please check the quantity in procurement order(s) for the product "%s", it should not be 0 or less!' % procurement.product_id.name)) - - raise osv.except_osv(_('Insufficient Data!'), - _('Quantity in procurement order(s) must be greater than 0.')) - if procurement.product_id.type in ('product', 'consu'): if not procurement.move_id: source = procurement.location_id.id From 27010a32ec33107d658f932ed2b5b8a0d36ae9d5 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 24 Aug 2012 18:02:03 +0530 Subject: [PATCH 110/726] [IMP]add access rights bzr revid: sgo@tinyerp.com-20120824123203-4kmu02cyehbqd48v --- addons/mail/security/ir.model.access.csv | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv index 1979e2fec05..1e88e4e5a12 100644 --- a/addons/mail/security/ir.model.access.csv +++ b/addons/mail/security/ir.model.access.csv @@ -1,9 +1,10 @@ -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,0,0 -access_mail_message_group_user,mail.message.group.user,model_mail_message,base.group_user,1,1,1,1 -access_mail_thread,mail.thread,model_mail_thread,base.group_user,1,1,1,0 -access_mail_followers_all,mail.followers.all,model_mail_followers,,1,1,1,1 -access_mail_notification_all,mail.notification.all,model_mail_notification,,1,1,1,1 -access_mail_group,mail.group,model_mail_group,base.group_user,1,1,1,1 -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 +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 0 0 +access_mail_message_group_user mail.message.group.user model_mail_message base.group_user 1 1 1 1 +access_mail_thread mail.thread model_mail_thread base.group_user 1 1 1 0 +access_mail_followers_all mail.followers.all model_mail_followers 1 1 1 1 +access_mail_notification_all mail.notification.all model_mail_notification 1 1 1 1 +access_mail_group mail.group model_mail_group base.group_user 1 1 1 1 +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 mode_mail_message_subtype 1 1 1 1 From af5583bb93822f4a5c8d2c48ddfb5a9cfd208fd8 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Mon, 27 Aug 2012 10:59:20 +0530 Subject: [PATCH 111/726] [IMP]:improved view bzr revid: apa@tinyerp.com-20120827052920-e7dwg2vqj0swnwqk --- addons/mail/static/src/xml/mail_followers.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index d590407494f..1a93d860b53 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -11,12 +11,12 @@ +

          -
            @@ -33,7 +33,7 @@ record_thread.subtype template Template used to display subtype of record --> -
          • +
          • @@ -44,6 +44,6 @@
            - +
            From 1338046cf0f7d37f724a09899695b7e02a5b873c Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Mon, 27 Aug 2012 10:59:33 +0530 Subject: [PATCH 112/726] [IMP]added access to mail_message_subtype bzr revid: sgo@tinyerp.com-20120827052933-6ajhaete5vuzqhiv --- addons/mail/security/ir.model.access.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv index 1979e2fec05..61106fbf234 100644 --- a/addons/mail/security/ir.model.access.csv +++ b/addons/mail/security/ir.model.access.csv @@ -7,3 +7,4 @@ access_mail_notification_all,mail.notification.all,model_mail_notification,,1,1, access_mail_group,mail.group,model_mail_group,base.group_user,1,1,1,1 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 \ No newline at end of file From 5a8bdae6d684cc4e4c9140ff971aaa5c552e7925 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Mon, 27 Aug 2012 11:25:39 +0530 Subject: [PATCH 113/726] [IMP]:improved view bzr revid: apa@tinyerp.com-20120827055539-kqybbq2sqhx9tax9 --- addons/mail/static/src/js/mail_followers.js | 12 ++++++------ addons/mail/static/src/xml/mail_followers.xml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index c6a83817af9..f81919de1c7 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -43,7 +43,7 @@ openerp_mail_followers = function(session, mail) { this.view.on("change:actual_mode", this, this._check_visibility); this._check_visibility(); this.fetch_subtype(); - this.$el.find('ul.oe_mail_recthread_subtype').click(function () { + this.$el.find('div.oe_mail_recthread_subtype').click(function () { var subtypelist = new Array(); _($(this).find('.oe_msg_subtype_check')).each(function (record){ if($(record).is(':checked')) { @@ -55,7 +55,7 @@ openerp_mail_followers = function(session, mail) { if (! this.params.display_control) { this.$el.find('button.oe_mail_button_followers').hide(); - this.$el.find('ul.oe_mail_recthread_subtype').hide() + this.$el.find('div.oe_mail_recthread_subtype').hide() } this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); @@ -85,7 +85,7 @@ openerp_mail_followers = function(session, mail) { this.$el.find('button.oe_mail_button_followers').html('Hide followers') this.$el.find('button.oe_mail_button_follow').hide(); this.$el.find('button.oe_mail_button_unfollow').hide(); - this.$el.find('ul.oe_mail_recthread_subtype').hide() + this.$el.find('div.oe_mail_recthread_subtype').hide() }, set_value: function(value_) { @@ -118,17 +118,17 @@ openerp_mail_followers = function(session, mail) { if (this.is_subscriber) { this.$el.find('button.oe_mail_button_follow').hide(); this.$el.find('button.oe_mail_button_unfollow').show(); - this.$el.find('ul.oe_mail_recthread_subtype').show(); } + this.$el.find('div.oe_mail_recthread_subtype').show(); } else { this.$el.find('button.oe_mail_button_follow').show(); this.$el.find('button.oe_mail_button_unfollow').hide(); - this.$el.find('ul.oe_mail_recthread_subtype').hide() } + this.$el.find('div.oe_mail_recthread_subtype').hide() } }, // Display the subtypes of each records. display_subtype: function(records) { var self = this - var subtype_list = this.$el.find('ul.oe_mail_recthread_subtype').empty(); + var subtype_list = this.$el.find('div.oe_mail_recthread_subtype').empty(); var follower_ids = this.follower_model.call('search',[[['res_model','=',this.ds_model.model],['res_id','=',this.view.datarecord.id],['user_id','=',this.session.uid]]]) follower_ids.then(function (record){ var follower_read = self.follower_model.call('read', [record,['subtype_ids']]); diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index 1a93d860b53..2f7f5e6cde8 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -11,7 +11,7 @@ -
              +

              From dd6e836c61ea20fc28cafbab96909fa88bbd2115 Mon Sep 17 00:00:00 2001 From: Yann papouin <> Date: Mon, 27 Aug 2012 15:32:46 +0530 Subject: [PATCH 114/726] [FIX] project_mrp : Fixes the problem of procurement for service product. lp bug: https://launchpad.net/bugs/997642 fixed bzr revid: amb@tinyerp.com-20120827100246-y9d38makz4iumlk0 --- addons/project_mrp/project_procurement.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/project_mrp/project_procurement.py b/addons/project_mrp/project_procurement.py index 299a74f52aa..a8c0ed6ab21 100644 --- a/addons/project_mrp/project_procurement.py +++ b/addons/project_mrp/project_procurement.py @@ -37,8 +37,9 @@ class procurement_order(osv.osv): """ Checks if task is done or not. @return: True or False. """ - return all(proc.product_id.type != 'service' or (proc.task_id and proc.task_id.state in ('done', 'cancelled')) \ + res = all((proc.product_id.type != 'service') or ((proc.product_id.type == 'service') and (proc.product_id.procure_method == 'make_to_stock')) or (proc.task_id and proc.task_id.state in ('done', 'cancelled')) \ for proc in self.browse(cr, uid, ids, context=context)) + return res def check_produce_service(self, cr, uid, procurement, context=None): return True @@ -80,7 +81,7 @@ class procurement_order(osv.osv): 'project_id': project and project.id or False, 'company_id': procurement.company_id.id, },context=context) - self.write(cr, uid, [procurement.id], {'task_id': task_id, 'state': 'running'}, context=context) + self.write(cr, uid, [procurement.id], {'task_id': task_id, 'state': 'running', 'message':'from project: task created.'}, context=context) self.running_send_note(cr, uid, ids, context=None) return task_id From cf8c1611d5d55d0410af91cfb86e335943f81a8b Mon Sep 17 00:00:00 2001 From: "Ferdinand @ Camptocamp" <> Date: Mon, 27 Aug 2012 17:11:23 +0530 Subject: [PATCH 115/726] [FIX] allows to add lots to planned quantity lp bug: https://launchpad.net/bugs/1009245 fixed bzr revid: rmu@tinyerp.com-20120827114123-dpxrkfgeh28b1x3t --- addons/mrp/mrp_view.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index c394544574d..194f8ddd768 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -694,6 +694,7 @@ +
              +

                -
                    From 5eed2be266d4dd2d12280ba06b467f3fd54387be Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 31 Aug 2012 14:40:43 +0530 Subject: [PATCH 141/726] [IMP]minor changes bzr revid: sgo@tinyerp.com-20120831091043-4rix3ozakssbxrgn --- addons/mail/mail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index abe5c296218..972227e120f 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -577,7 +577,7 @@ class mail_thread(osv.Model): self.message_post(cr, uid, [id], message, context=context) def message_post(self, cr, uid, thread_id, body='', subject=False, - msg_type='notification', parent_id=False, attachments=None, context=None, **kwargs): + msg_type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs): """ Post a new message in an existing message thread, returning the new mail.message ID. Extra keyword arguments will be used as default column values for the new mail.message record. From ca22d79a2107d943f1484728cdda7b6d37f43826 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 14:42:06 +0530 Subject: [PATCH 142/726] [IMP] Add data of subtype in procurement bzr revid: fka@tinyerp.com-20120831091206-196wzqlatj7lryi0 --- addons/procurement/procurement.py | 12 ++++----- addons/procurement/procurement_data.xml | 34 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index db50ebd94fd..4c60316ffb6 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -496,22 +496,22 @@ class procurement_order(osv.osv): return obj_id def create_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been created."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been created."), subtype="new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been confirmed."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been confirmed."), subtype="confirmed", context=context) def running_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been set to running."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been set to running."), subtype="running", context=context) def ready_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been set to ready."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been set to ready."), subtype="ready", context=context) def cancel_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype="cancel", context=context) def done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been done."), context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype="close", context=context) procurement_order() diff --git a/addons/procurement/procurement_data.xml b/addons/procurement/procurement_data.xml index 6a83d525c68..bbcaa33d2a1 100644 --- a/addons/procurement/procurement_data.xml +++ b/addons/procurement/procurement_data.xml @@ -28,5 +28,39 @@ 1 1 + + + + + + + confirmed + + + + ready + + + + running + + + + + + + + + + + + + + + + + \ No newline at end of file From 17ef40f428cbe12358e5bd54efa3c66ecf8e1b0c Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Fri, 31 Aug 2012 15:30:12 +0530 Subject: [PATCH 143/726] [IMP]add the data into event for subtype bzr revid: rma@tinyerp.com-20120831100012-mlzik593orznp9aj --- addons/event/__openerp__.py | 1 + addons/event/event.py | 20 ++++++++++---------- addons/event/event_data.xml | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py index 1e548f68991..428ebb4cb06 100644 --- a/addons/event/__openerp__.py +++ b/addons/event/__openerp__.py @@ -46,6 +46,7 @@ Note that: 'data': [ 'security/event_security.xml', 'security/ir.model.access.csv', + 'event_data.xml', 'wizard/event_confirm_view.xml', 'event_view.xml', 'report/report_event_registration_view.xml', diff --git a/addons/event/event.py b/addons/event/event.py index 763aa423378..c3284695ab9 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -264,27 +264,27 @@ class event_event(osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Event has been created.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="new", context=context) return True def button_cancel_send_note(self, cr, uid, ids, context=None): message = _("Event has been cancelled.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="cancel", context=context) return True def button_draft_send_note(self, cr, uid, ids, context=None): message = _("Event has been set to draft.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="new", context=context) return True def button_done_send_note(self, cr, uid, ids, context=None): message = _("Event has been done.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="close", context=context) return True def button_confirm_send_note(self, cr, uid, ids, context=None): message = _("Event has been confirmed.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="confirm", context=context) return True event_event() @@ -331,7 +331,7 @@ class event_registration(osv.osv): def confirm_registration(self, cr, uid, ids, context=None): self.message_post(cr, uid, ids, body=_('State set to open'), context=context) - return self.write(cr, uid, ids, {'state': 'open'}, context=context) + return self.write(cr, uid, ids, {'state': 'open'}, subtype="open", context=context) def create(self, cr, uid, vals, context=None): obj_id = super(event_registration, self).create(cr, uid, vals, context) @@ -360,13 +360,13 @@ class event_registration(osv.osv): if today >= registration.event_id.date_begin: values = {'state': 'done', 'date_closed': today} self.write(cr, uid, ids, values) - self.message_post(cr, uid, ids, body=_('State set to Done'), context=context) + self.message_post(cr, uid, ids, body=_('State set to Done'), subtype="close", context=context) else: raise osv.except_osv(_('Error!'),_("You must wait for the starting day of the event to do this action.") ) return True def button_reg_cancel(self, cr, uid, ids, context=None, *args): - self.message_post(cr, uid, ids, body=_('State set to Cancel'), context=context) + self.message_post(cr, uid, ids, body=_('State set to Cancel'), subtype="cancel", context=context) return self.write(cr, uid, ids, {'state': 'cancel'}) def mail_user(self, cr, uid, ids, context=None): @@ -436,12 +436,12 @@ class event_registration(osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Registration has been created.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="new", context=context) return True def do_draft_send_note(self, cr, uid, ids, context=None): message = _("Registration has been set as draft.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="new", context=context) return True event_registration() diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml index 83af2f35cfb..0498d3e490b 100644 --- a/addons/event/event_data.xml +++ b/addons/event/event_data.xml @@ -12,6 +12,38 @@ automatic 100 + + new + + + + + close + + + + cancel + + + + + confirm + + + + + open + + + + + + + + + + + @@ -20,5 +52,6 @@ From the top menu Events, you can organize events, manage registrations, automate communication around your event and sell events through your quotations. Module Events Organisation has been installed + From 90e55a5337694a15131bfac9a3d705ee25723052 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 31 Aug 2012 15:33:18 +0530 Subject: [PATCH 144/726] [IMP]remove unused method and improve code bzr revid: sgo@tinyerp.com-20120831100318-t2e2wv81trwfpc7u --- addons/mail/mail_thread.py | 6 +++--- addons/mail/static/src/js/mail_followers.js | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 972227e120f..2d31a9ad3ba 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -711,8 +711,8 @@ class mail_thread(osv.Model): return True def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None): - subscription_obj = self.pool.get('mail.followers') - subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) - return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one + followers_obj = self.pool.get('mail.followers') + followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 1601f3aaf46..fc9223b3657 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -40,11 +40,7 @@ openerp_mail_followers = function(session, mail) { this._check_visibility(); this.fetch_subtype(); this.$el.find('ul.oe_mail_recthread_subtype').click(function () {self.update_subtype();}) - this.$el.find('button.oe_mail_button_follow').click(function () { - self.do_follow(); - self.fetch_subtype(); - }) - this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); }) + this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); self.fetch_subtype();}) .mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) .mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); this.$el.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); }) From a6a3d4eda6427fc1470e1bfd8408ba90581ad9e9 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 16:10:32 +0530 Subject: [PATCH 145/726] [IMP] set indentation in purchase_requisition.xml bzr revid: fka@tinyerp.com-20120831104032-yfuugotohlgfvz75 --- .../purchase_requisition_data.xml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/addons/purchase_requisition/purchase_requisition_data.xml b/addons/purchase_requisition/purchase_requisition_data.xml index 211f51374dd..11ac73a6dd2 100644 --- a/addons/purchase_requisition/purchase_requisition_data.xml +++ b/addons/purchase_requisition/purchase_requisition_data.xml @@ -6,17 +6,18 @@ id="purchase_default_set" model="ir.values" name="set"/> - + + close - - - - - - - + + + + + + + From 31064b1855a60bf211c4a6f0abcb304865ee692e Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Fri, 31 Aug 2012 16:11:43 +0530 Subject: [PATCH 146/726] fix data bzr revid: apa@tinyerp.com-20120831104143-1ymb932kpng3bu3z --- addons/sale/sale_data.xml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/addons/sale/sale_data.xml b/addons/sale/sale_data.xml index a9c0e18a415..fceb806b3a2 100644 --- a/addons/sale/sale_data.xml +++ b/addons/sale/sale_data.xml @@ -41,14 +41,13 @@ - - mail.group - - notification - Sales Management application installed! - This application lets you create and send quotations and process your sales orders; from delivery to invoicing. -If you need to manage your sales pipeline (leads, opportunities, phonecalls), you can install the module <i>CRM</i> from the top menu Settings. + + + The Sales Management application has been installed. + This modules allows you to create and send easily quotations and process your sales orders; from the delivery to the invoicing. + +If you need to manage your sales pipeline (leads, opportunities, phonecalls), you can install the module <i>CRM</i> from the top menu Settings. From 139ee97562ec45549e35ac747bd6c2ae53360c58 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Fri, 31 Aug 2012 16:15:40 +0530 Subject: [PATCH 147/726] typo bzr revid: apa@tinyerp.com-20120831104540-oixjx4jpknk5hlcc --- addons/sale/sale_data.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sale_data.xml b/addons/sale/sale_data.xml index fceb806b3a2..a23ab401dbd 100644 --- a/addons/sale/sale_data.xml +++ b/addons/sale/sale_data.xml @@ -56,7 +56,7 @@ If you need to manage your sales pipeline (leads, opportunities, phonecalls), yo - cancel + cancelled From 1100d6b1cceb2cf74edf3b68f19d1a74b1c35c0c Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Fri, 31 Aug 2012 16:21:17 +0530 Subject: [PATCH 148/726] typo bzr revid: apa@tinyerp.com-20120831105117-mjm99cs7ko8pmkfq --- addons/sale/sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 9628c4fdc91..a407be80c99 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1035,7 +1035,7 @@ class sale_order(osv.osv): def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), subtype="cancel", context=context) + self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), subtype="cancelled", context=context) def delivery_send_note(self, cr, uid, ids, picking_id, context=None): for order in self.browse(cr, uid, ids, context=context): From d621d8fae3ca98ccd0cfffd56413459421069655 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 16:24:22 +0530 Subject: [PATCH 149/726] [IMP] improve code bzr revid: fka@tinyerp.com-20120831105422-m2unzh8mezt4oan4 --- addons/stock/stock.py | 2 +- addons/stock/stock_data.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 5e8b5dfaf5d..3011fc6c6c2 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1398,7 +1398,7 @@ class stock_picking(osv.osv): def ship_cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), subtype="cancel", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), subtype="cancelled", context=context) stock_picking() diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index a24502ab361..976c89ad06f 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -181,7 +181,7 @@ watch your stock valuation, and track production lots upstream and downstream (b close - + From 6c04925c0f3521a5a99586f688727f2be5f6340b Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 16:28:55 +0530 Subject: [PATCH 150/726] [IMP] improve code bzr revid: fka@tinyerp.com-20120831105855-crs13rnqi2uztgha --- addons/purchase/purchase.py | 2 +- addons/purchase/purchase_data.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 81b851eb2a2..16b827c1323 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -766,7 +766,7 @@ class purchase_order(osv.osv): def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), subtype="cancel", context=context) + self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), subtype="cancelled", context=context) purchase_order() diff --git a/addons/purchase/purchase_data.xml b/addons/purchase/purchase_data.xml index 1cc3b3b014b..a84564b2360 100644 --- a/addons/purchase/purchase_data.xml +++ b/addons/purchase/purchase_data.xml @@ -67,8 +67,8 @@ You can also manage purchase requisitions, see also the Purchase Settings.received - - cancel + + cancelled From d32908a359dcba66b032ee4dcfca7dd2142b94d6 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Fri, 31 Aug 2012 16:30:00 +0530 Subject: [PATCH 151/726] [IMP]make changes for the calcelled state into event bzr revid: rma@tinyerp.com-20120831110000-cd022yy58aken0iw --- addons/event/event.py | 4 ++-- addons/event/event_data.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/event/event.py b/addons/event/event.py index c3284695ab9..feb0aed9d46 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -269,7 +269,7 @@ class event_event(osv.osv): def button_cancel_send_note(self, cr, uid, ids, context=None): message = _("Event has been cancelled.") - self.message_post(cr, uid, ids, body=message, subtype="cancel", context=context) + self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) return True def button_draft_send_note(self, cr, uid, ids, context=None): @@ -366,7 +366,7 @@ class event_registration(osv.osv): return True def button_reg_cancel(self, cr, uid, ids, context=None, *args): - self.message_post(cr, uid, ids, body=_('State set to Cancel'), subtype="cancel", context=context) + self.message_post(cr, uid, ids, body=_('State set to Cancel'), subtype="cancelled", context=context) return self.write(cr, uid, ids, {'state': 'cancel'}) def mail_user(self, cr, uid, ids, context=None): diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml index 65713628de9..bc16fc08aee 100644 --- a/addons/event/event_data.xml +++ b/addons/event/event_data.xml @@ -21,8 +21,8 @@ close - - cancel + + cancelled From 6c56f95e869f21d5eaecb3c3eda1de831e1d5499 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 16:34:43 +0530 Subject: [PATCH 152/726] [IMP] improve code bzr revid: fka@tinyerp.com-20120831110443-55nxhelq1dfl073j --- addons/idea/idea.py | 2 +- addons/idea/idea_data.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/idea/idea.py b/addons/idea/idea.py index a20ddf51414..ff55e6afbc3 100644 --- a/addons/idea/idea.py +++ b/addons/idea/idea.py @@ -67,7 +67,7 @@ class idea_idea(osv.osv): def idea_cancel(self, cr, uid, ids, context={}): self.write(cr, uid, ids, { 'state': 'cancel' }) - self.message_post(cr, uid, ids, body=_('Idea canceled.'), subtype="cancel", context=context) + self.message_post(cr, uid, ids, body=_('Idea canceled.'), subtype="cancelled", context=context) return True def idea_open(self, cr, uid, ids, context={}): diff --git a/addons/idea/idea_data.xml b/addons/idea/idea_data.xml index a4cd4970511..17401f72f98 100644 --- a/addons/idea/idea_data.xml +++ b/addons/idea/idea_data.xml @@ -26,8 +26,8 @@ open - - cancel + + cancelled From 5ec28dcd8933cb8ef42d3349d7651e66b02d46f5 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 16:41:15 +0530 Subject: [PATCH 153/726] [IMP] improve code bzr revid: fka@tinyerp.com-20120831111115-fqoapz8uroxsdddm --- addons/procurement/procurement.py | 2 +- addons/procurement/procurement_data.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 4c60316ffb6..d59a894bc2b 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -508,7 +508,7 @@ class procurement_order(osv.osv): self.message_post(cr, uid, ids, body=_("Procurement has been set to ready."), subtype="ready", context=context) def cancel_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype="cancel", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype="cancelled", context=context) def done_send_note(self, cr, uid, ids, context=None): self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype="close", context=context) diff --git a/addons/procurement/procurement_data.xml b/addons/procurement/procurement_data.xml index bbcaa33d2a1..8f4e945a7de 100644 --- a/addons/procurement/procurement_data.xml +++ b/addons/procurement/procurement_data.xml @@ -47,7 +47,7 @@ running - + From e5b99dca25aea687272e0e09d73d9ac034acd14c Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 18:11:23 +0530 Subject: [PATCH 154/726] [IMP] change close bzr revid: fka@tinyerp.com-20120831124123-3fq363k7b5bcnuix --- addons/procurement/procurement.py | 2 +- addons/procurement/procurement_data.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index d59a894bc2b..94d83675df1 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -511,7 +511,7 @@ class procurement_order(osv.osv): self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype="cancelled", context=context) def done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype="close", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype="closed", context=context) procurement_order() diff --git a/addons/procurement/procurement_data.xml b/addons/procurement/procurement_data.xml index 8f4e945a7de..bd44f0caee5 100644 --- a/addons/procurement/procurement_data.xml +++ b/addons/procurement/procurement_data.xml @@ -50,7 +50,7 @@ - + From 596debf67e4792755c72b629cd481d7cdb653292 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Fri, 31 Aug 2012 18:17:22 +0530 Subject: [PATCH 155/726] [IMP]make changes into account data for subtype bzr revid: rma@tinyerp.com-20120831124722-2u9fcx10gnrcfsl5 --- addons/account/data/account_data.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml index 589683055d8..fe0c864e72f 100644 --- a/addons/account/data/account_data.xml +++ b/addons/account/data/account_data.xml @@ -518,7 +518,6 @@ - Account Reconcile account.reconcile @@ -554,8 +553,6 @@ - - @@ -563,7 +560,7 @@ Invoice account.invoice - + new From 84fd3b3a35767140a0fcbc0aebb5a4439fcd4e79 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 18:17:44 +0530 Subject: [PATCH 156/726] [IMP] change subtype close bzr revid: fka@tinyerp.com-20120831124744-uup75dwshj5nmf2n --- addons/purchase_requisition/purchase_requisition.py | 2 +- addons/purchase_requisition/purchase_requisition_data.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index 67905f35922..5a5f669b1a1 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -97,7 +97,7 @@ class purchase_requisition(osv.osv): self.message_post(cr, uid, ids, body=_("Purchase Requisition has been set to draft."), subtype="new", context=context) def done_to_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Purchase Requisition has been done."), subtype="close", context=context) + self.message_post(cr, uid, ids, body=_("Purchase Requisition has been done."), subtype="closed", context=context) def cancel_send_note(self, cr, uid, ids, context=None): self.message_post(cr, uid, ids, body=_("Purchase Requisition has been cancelled."), subtype="cancel", context=context) diff --git a/addons/purchase_requisition/purchase_requisition_data.xml b/addons/purchase_requisition/purchase_requisition_data.xml index 11ac73a6dd2..11dd5f45170 100644 --- a/addons/purchase_requisition/purchase_requisition_data.xml +++ b/addons/purchase_requisition/purchase_requisition_data.xml @@ -7,8 +7,8 @@ model="ir.values" name="set"/> - - close + + closed From de9f0c9777800cb398afddc8466c6a5c9ea3056e Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 18:22:01 +0530 Subject: [PATCH 157/726] [IMP] change subtype close bzr revid: fka@tinyerp.com-20120831125201-gomz1f0hy8wid1rh --- addons/stock/stock.py | 2 +- addons/stock/stock_data.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3011fc6c6c2..0bc455a149c 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1394,7 +1394,7 @@ class stock_picking(osv.osv): 'internal': 'moved', } for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype="close", context=context) + self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype="closed", context=context) def ship_cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index 976c89ad06f..a7e2ffdd562 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -177,8 +177,8 @@ watch your stock valuation, and track production lots upstream and downstream (b moved - - close + + closed From e44d125479d9208d3d2d9b0b64b655b530a07eae Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Fri, 31 Aug 2012 18:47:12 +0530 Subject: [PATCH 158/726] [IMP] Add data of subtype in mrp, mrp_repair & mrp_operations bzr revid: fka@tinyerp.com-20120831131712-dz5b5isq797v5xfc --- addons/mrp/mrp.py | 10 ++-- addons/mrp/mrp_data.xml | 33 ++++++++++++++ addons/mrp_operations/mrp_operation_data.xml | 34 ++++++++++++++ addons/mrp_operations/mrp_operations.py | 10 ++-- addons/mrp_repair/__openerp__.py | 1 + addons/mrp_repair/mrp_repair.py | 14 +++--- addons/mrp_repair/mrp_repair_data.xml | 48 ++++++++++++++++++++ 7 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 addons/mrp_repair/mrp_repair_data.xml diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index c667daadbec..a9f6290c58a 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -1047,27 +1047,27 @@ class mrp_production(osv.osv): # --------------------------------------------------- def create_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Manufacturing order has been created."), context=context) + self.message_post(cr, uid, ids, body=_("Manufacturing order has been created."), subtype="new", context=context) return True def action_cancel_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order has been canceled.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) return True def action_ready_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order is ready to produce.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="ready", context=context) return True def action_in_production_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order is in production.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="production", context=context) return True def action_done_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order has been done.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) return True def action_confirm_send_note(self, cr, uid, ids, context=None): diff --git a/addons/mrp/mrp_data.xml b/addons/mrp/mrp_data.xml index 0bbf2d3b64c..6ee7cc82dd2 100644 --- a/addons/mrp/mrp_data.xml +++ b/addons/mrp/mrp_data.xml @@ -27,5 +27,38 @@ From the Manufacturing Settings, you can choose to compute production schedules 1 + + new + + + + + ready + + + + + production + + + + cancelled + + + + + closed + + + + + + + + + + + + diff --git a/addons/mrp_operations/mrp_operation_data.xml b/addons/mrp_operations/mrp_operation_data.xml index ff83fdc7e8b..e2d7f9f0a56 100644 --- a/addons/mrp_operations/mrp_operation_data.xml +++ b/addons/mrp_operations/mrp_operation_data.xml @@ -30,5 +30,39 @@ done + + + new + + + + + started + + + + + pending + + + + cancelled + + + + + closed + + + + + + + + + + + + diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index ee2547bc7df..a18eb4141ba 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -224,7 +224,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been created for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype="new", context=context) return True def action_start_send_note(self, cr, uid, ids, context=None): @@ -232,7 +232,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been started for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype="started", context=context) return True def action_done_send_note(self, cr, uid, ids, context=None): @@ -240,7 +240,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been done for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype="closed", context=context) return True def action_pending_send_note(self, cr, uid, ids, context=None): @@ -248,7 +248,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order is pending for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype="pending", context=context) return True def action_cancel_send_note(self, cr, uid, ids, context=None): @@ -256,7 +256,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been cancelled for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype="cancelled", context=context) return True mrp_production_workcenter_line() diff --git a/addons/mrp_repair/__openerp__.py b/addons/mrp_repair/__openerp__.py index da4070d6210..13a6e81e141 100644 --- a/addons/mrp_repair/__openerp__.py +++ b/addons/mrp_repair/__openerp__.py @@ -43,6 +43,7 @@ The following topics should be covered by this module: 'data': [ 'security/ir.model.access.csv', 'security/mrp_repair_security.xml', + 'mrp_repair_data.xml', 'mrp_repair_sequence.xml', 'wizard/mrp_repair_cancel_view.xml', 'wizard/mrp_repair_make_invoice_view.xml', diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index c1ac8f809ce..44624044090 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -571,40 +571,40 @@ class mrp_repair(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Repair Order for %s has been created." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype="new", context=context) return True def set_start_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Repair Order for %s has been started." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype="started", context=context) return True def set_toinvoiced_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Draft Invoice of %s %s waiting for validation.") % (repair.invoice_id.amount_total, repair.invoice_id.currency_id.symbol) - self.message_post(cr, uid, [repair.id], body=message, context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype="pending", context=context) return True def set_confirm_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _( "Repair Order for %s has been accepted." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype="accepted", context=context) return True def set_cancel_send_note(self, cr, uid, ids, context=None): message = _("Repair has been cancelled.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) return True def set_ready_send_note(self, cr, uid, ids, context=None): message = _("Repair Order is now ready to repair.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="ready", context=context) return True def set_done_send_note(self, cr, uid, ids, context=None): message = _("Repair Order is closed.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) return True mrp_repair() diff --git a/addons/mrp_repair/mrp_repair_data.xml b/addons/mrp_repair/mrp_repair_data.xml new file mode 100644 index 00000000000..337a4113382 --- /dev/null +++ b/addons/mrp_repair/mrp_repair_data.xml @@ -0,0 +1,48 @@ + + + + + + new + + + + + started + + + + + ready + + + + + pending + + + + accepted + + + + cancelled + + + + + closed + + + + + + + + + + + + + + From aa216774eab92cd4334a9bbbdbf50293b26d5565 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 3 Sep 2012 11:47:13 +0530 Subject: [PATCH 159/726] [IMP] make changes into account data for the subtype bzr revid: rma@tinyerp.com-20120903061713-xuhcfdqi4e7cp6qf --- addons/account/account_invoice.py | 2 +- addons/account/data/account_data.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index e8e935a9505..5f81cbfe857 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1306,7 +1306,7 @@ class account_invoice(osv.osv): def invoice_cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype="cancel", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype="cancelled", context=context) account_invoice() class account_invoice_line(osv.osv): diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml index fe0c864e72f..bf3b3152552 100644 --- a/addons/account/data/account_data.xml +++ b/addons/account/data/account_data.xml @@ -569,12 +569,12 @@ paid - - cancel + + cancelled - + From 23007e8aebbd269abfbf3f62f27e8cbbcecafb33 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 3 Sep 2012 14:27:28 +0530 Subject: [PATCH 160/726] [IMP] Add picking_in & picking_out object in stock bzr revid: fka@tinyerp.com-20120903085728-vx5hbkug5527nolo --- addons/stock/stock_data.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index a7e2ffdd562..3539d5b5056 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -171,27 +171,27 @@ watch your stock valuation, and track production lots upstream and downstream (b Mail: mail.message.subtype --> - + moved - + closed - + - + - + - + - + From 49722c77c05375ad2f04c716cda3599f1c5bd5e8 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 3 Sep 2012 18:04:05 +0530 Subject: [PATCH 161/726] [IMP] add received & delivered subtype in stock bzr revid: fka@tinyerp.com-20120903123405-7rmte2src1xtdghp --- addons/stock/stock.py | 2 +- addons/stock/stock_data.xml | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 0bc455a149c..ed20bbec2c5 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1394,7 +1394,7 @@ class stock_picking(osv.osv): 'internal': 'moved', } for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype="closed", context=context) + self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype=type_dict.get(obj.type), context=context) def ship_cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index 3539d5b5056..f83b0ada388 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -171,27 +171,29 @@ watch your stock valuation, and track production lots upstream and downstream (b Mail: mail.message.subtype --> - + - - moved - + + delivered + + - - closed - + + received + + - + - + - + - + From df3aa41ac443d22511dc4cf4732629e109c15ef1 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Sep 2012 12:47:54 +0530 Subject: [PATCH 162/726] [IMP] add subtype data in hr module bzr revid: rma@tinyerp.com-20120904071754-d99h6iey5nzrjf08 --- addons/hr_holidays/hr_holidays.py | 12 +++--- addons/hr_holidays/hr_holidays_data.xml | 38 +++++++++++++++++++ addons/hr_recruitment/hr_recruitment.py | 14 +++---- addons/hr_recruitment/hr_recruitment_data.xml | 36 +++++++++++++++++- .../hr_timesheet_invoice.py | 8 ++-- .../hr_timesheet_invoice_data.xml | 28 ++++++++++++++ 6 files changed, 118 insertions(+), 18 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 759170224bd..e0358efe0d9 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -364,32 +364,32 @@ class hr_holidays(osv.osv): def create_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): self.message_post(cr, uid, ids, - _("The request has been created and is waiting confirmation."), context=context) + _("The request has been created and is waiting confirmation."),subtype="new", context=context) return True def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_post(cr, uid, [obj.id], - _("The request has been submitted and is waiting for validation by the manager."), context=context) + _("The request has been submitted and is waiting for validation by the manager."), subtype="submitted", context=context) def holidays_first_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): self.message_post(cr, uid, [obj.id], - _("The request has been approved. A second validation is necessary and is now pending."), context=context) + _("The request has been approved. A second validation is necessary and is now pending."), subtype="pending", context=context) def holidays_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): if obj.double_validation: self.message_post(cr, uid, [obj.id], - _("The request has been double validated. The validation process is now over."), context=context) + _("The request has been double validated. The validation process is now over."), subtype="double validated", context=context) else: self.message_post(cr, uid, [obj.id], - _("The request has been approved. The validation process is now over."), context=context) + _("The request has been approved. The validation process is now over."), subtype="closed", context=context) def holidays_refuse_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_post(cr, uid, [obj.id], - _("The request has been refused. The validation process is now over."), context=context) + _("The request has been refused. The validation process is now over."), subtype="cancelled", context=context) class resource_calendar_leaves(osv.osv): diff --git a/addons/hr_holidays/hr_holidays_data.xml b/addons/hr_holidays/hr_holidays_data.xml index 1e534093eb3..3b927b60419 100644 --- a/addons/hr_holidays/hr_holidays_data.xml +++ b/addons/hr_holidays/hr_holidays_data.xml @@ -49,5 +49,43 @@ Once validated, they are visible in the employee's calendar. HR officers can def True brown + + + new + + + + + submitted + + + + + pending + + + + + double validated + + + + closed + + + + cancelled + + + + + + + + + + + + diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 82f2c9c3a21..578ebde9162 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -457,14 +457,14 @@ class hr_applicant(base_stage, osv.Model): """ Override of the (void) default notification method. """ if not stage_id: return True stage_name = self.pool.get('hr.recruitment.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change", context=context) def case_get_note_msg_prefix(self, cr, uid, id, context=None): return 'Applicant' def case_open_send_note(self, cr, uid, ids, context=None): message = _("Applicant has been set in progress.") - return self.message_post(cr, uid, ids, body=message, context=context) + return self.message_post(cr, uid, ids, body=message, subtype="in progress", context=context) def case_close_send_note(self, cr, uid, ids, context=None): if context is None: @@ -472,23 +472,23 @@ class hr_applicant(base_stage, osv.Model): for applicant in self.browse(cr, uid, ids, context=context): if applicant.emp_id: message = _("Applicant has been hired and created as an employee.") - self.message_post(cr, uid, [applicant.id], body=message, context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype="closed", context=context) else: message = _("Applicant has been hired.") - self.message_post(cr, uid, [applicant.id], body=message, context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype="closed", context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): msg = 'Applicant refused.' - return self.message_post(cr, uid, ids, body=msg, context=context) + return self.message_post(cr, uid, ids, body=msg, subtype="cancelled", context=context) def case_reset_send_note(self, cr, uid, ids, context=None): message =_("Applicant has been set as new.") - return self.message_post(cr, uid, ids, body=message, context=context) + return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) def create_send_note(self, cr, uid, ids, context=None): message = _("Applicant has been created.") - return self.message_post(cr, uid, ids, body=message, context=context) + return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) class hr_job(osv.osv): diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml index 84289da7bae..a567489751a 100644 --- a/addons/hr_recruitment/hr_recruitment_data.xml +++ b/addons/hr_recruitment/hr_recruitment_data.xml @@ -460,6 +460,40 @@ You can automatically receive job application though an email gateway, see the H - + + + + new + + + + + closed + + + + cancelled + + + + + stage change + + + + + in progress + + + + + + + + + + + + diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py index a1562d53a61..4ed61119a5f 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py @@ -95,25 +95,25 @@ class account_analytic_account(osv.osv): def set_close(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'close'}, context=context) message = _("Contract has been closed.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) return True def set_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'cancelled'}, context=context) message = _("Contract has been cancelled.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) return True def set_open(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'open'}, context=context) message = _("Contract has been opened.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="open", context=context) return True def set_pending(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'pending'}, context=context) message = _("Contract has been set as pending.") - self.message_post(cr, uid, ids, body=message, context=context) + self.message_post(cr, uid, ids, body=message, subtype="pending", context=context) return True account_analytic_account() diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml b/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml index 462888e0b39..5cc5024d591 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml @@ -16,5 +16,33 @@ 50% 50.0 + + + closed + + + + pending + + + + + open + + + + cancelled + + + + + + + + + + + + From d473fb95a3c9acf4048b8bd218f1837d4a1057dd Mon Sep 17 00:00:00 2001 From: "jri@openerp.com" <> Date: Tue, 4 Sep 2012 10:15:27 +0200 Subject: [PATCH 163/726] Order of the views is already defined in open_view_employee_list_my's view_mode. This code added nothing and made it more difficult to override the order in inherited modules. bzr revid: jri@openerp.com-20120904081527-379csy03p4hq1g51 --- addons/hr/hr_view.xml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml index 99d7af027e9..79a26091651 100644 --- a/addons/hr/hr_view.xml +++ b/addons/hr/hr_view.xml @@ -198,25 +198,6 @@ - - - kanban - - - - - tree - - - - - - - form - - - - From 61118d78473a91cdc13ef753c5509fdf62d25e63 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Sep 2012 14:26:26 +0530 Subject: [PATCH 164/726] [IMP] add subtype data into project and project_issue module bzr revid: rma@tinyerp.com-20120904085626-klbtc8hrrksi4gy9 --- addons/project/project.py | 4 +-- addons/project/project_data.xml | 8 +++--- addons/project_issue/project_issue.py | 6 ++--- addons/project_issue/project_issue_data.xml | 27 ++++++++++++++++++++- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index ae70dcc1dd4..26e42a73539 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -525,11 +525,11 @@ def Project(): def set_cancel_send_note(self, cr, uid, ids, context=None): message = _("Project has been cancelled.") - return self.message_post(cr, uid, ids, body=message, subtype="cancel", context=context) + return self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) def set_close_send_note(self, cr, uid, ids, context=None): message = _("Project has been closed.") - return self.message_post(cr, uid, ids, body=message, subtype="close", context=context) + return self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) def write(self, cr, uid, ids, vals, context=None): # if alias_model has been changed, update alias_model_id accordingly diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml index 88afc08b961..c2e51fa8049 100644 --- a/addons/project/project_data.xml +++ b/addons/project/project_data.xml @@ -99,12 +99,12 @@ - - close + + closed - - cancel + + cancelled diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 9cc97ec470b..52bb2d2d687 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -500,7 +500,7 @@ class project_issue(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change", context=context) def case_get_note_msg_prefix(self, cr, uid, id, context=None): """ Override of default prefix for notifications. """ @@ -508,11 +508,11 @@ class project_issue(base_stage, osv.osv): def convert_to_task_send_note(self, cr, uid, ids, context=None): message = _("Project issue converted to task.") - return self.message_post(cr, uid, ids, body=message, context=context) + return self.message_post(cr, uid, ids, body=message, subtype="converted", context=context) def create_send_note(self, cr, uid, ids, context=None): message = _("Project issue created.") - return self.message_post(cr, uid, ids, body=message, context=context) + return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) def case_escalate_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): diff --git a/addons/project_issue/project_issue_data.xml b/addons/project_issue/project_issue_data.xml index ddb0d575e63..2501bd821d2 100644 --- a/addons/project_issue/project_issue_data.xml +++ b/addons/project_issue/project_issue_data.xml @@ -30,7 +30,32 @@ v3.0 - + + + + new + + + + + stage change + + + + + converted + + + + + + + + + + + + mail.group From 93f5c6b6a9265e30c7b7addb7eceeef57dbb7fb6 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Tue, 4 Sep 2012 15:01:11 +0530 Subject: [PATCH 165/726] [IMP]add unit test for message subtype bzr revid: sgo@tinyerp.com-20120904093111-hj291blbbkg39cey --- addons/mail/mail_thread.py | 1 - addons/mail/tests/test_mail.py | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 2d31a9ad3ba..241e6674b17 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -656,7 +656,6 @@ class mail_thread(osv.Model): subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)]) if subtype_ids: self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context) - # TDE: temp, must check followers widget return [] # return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index fd4b116b364..c27b3c6f68e 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -83,6 +83,7 @@ class test_mail(common.TransactionCase): self.mail_message = self.registry('mail.message') self.mail_notification = self.registry('mail.notification') self.mail_followers = self.registry('mail.followers') + self.mail_message_subtype = self.registry('mail.message.subtype') self.res_users = self.registry('res.users') self.res_partner = self.registry('res.partner') @@ -534,3 +535,37 @@ class test_mail(common.TransactionCase): msg1.refresh() self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages') self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now') + + def test_60_message_subtype(self): + """ Tests designed for message_subtype. """ + cr, uid = self.cr, self.uid + self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'}) + user_admin = self.res_users.browse(cr, uid, uid) + group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + + # 0 - Admin + p_a_id = user_admin.partner_id.id + # Subscribe #1, + self.mail_group_model_id = self.ir_model.search(cr, uid, [('model','=', 'mail.group')])[0] + subtype_ids = self.mail_message_subtype.search(cr, uid, []) + self.mail_message_subtype.write(cr,uid,subtype_ids,{'model_ids':[(4,self.mail_group_model_id )]}) + group_pigs.message_subscribe_users([uid]) + + # Mail data + _subject = 'Pigs' + _mail_subject = '%s posted on %s' % (user_admin.name, group_pigs.name) + _body1 = 'Pigs rules' + _mail_body1 = 'Pigs rules\n
                    Admin
                    \n' + _mail_bodyalt1 = 'Pigs rules\nAdmin' + _body2 = 'Pigs rules' + _mail_body2 = 'Pigs rules\n
                    Admin
                    \n' + _mail_bodyalt2 = 'Pigs rules\nAdmin\n' + filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)]) + # Post comment with body and subject, comment preference + msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, msg_type='comment',subtype='email') + notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)]) + self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall") + # New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message + msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, msg_type='email', subtype='other') + notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)]) + self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall") From e50afb97b4f2c5183fc5d60db5736ed822a2710f Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Sep 2012 15:10:52 +0530 Subject: [PATCH 166/726] [IMP] make changes into hr module for subtype data bzr revid: rma@tinyerp.com-20120904094052-5povh2fua010g3ej --- addons/hr_holidays/hr_holidays.py | 10 ++++----- addons/hr_holidays/hr_holidays_data.xml | 22 ++++--------------- addons/hr_recruitment/hr_recruitment.py | 4 ++-- addons/hr_recruitment/hr_recruitment_data.xml | 8 +++---- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index e0358efe0d9..4136abbb2f7 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -370,26 +370,26 @@ class hr_holidays(osv.osv): def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_post(cr, uid, [obj.id], - _("The request has been submitted and is waiting for validation by the manager."), subtype="submitted", context=context) + _("The request has been submitted and is waiting for validation by the manager."), context=context) def holidays_first_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): self.message_post(cr, uid, [obj.id], - _("The request has been approved. A second validation is necessary and is now pending."), subtype="pending", context=context) + _("The request has been approved. A second validation is necessary and is now pending."), context=context) def holidays_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): if obj.double_validation: self.message_post(cr, uid, [obj.id], - _("The request has been double validated. The validation process is now over."), subtype="double validated", context=context) + _("The request has been double validated. The validation process is now over."), context=context) else: self.message_post(cr, uid, [obj.id], - _("The request has been approved. The validation process is now over."), subtype="closed", context=context) + _("The request has been approved. The validation process is now over."), subtype="approved", context=context) def holidays_refuse_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_post(cr, uid, [obj.id], - _("The request has been refused. The validation process is now over."), subtype="cancelled", context=context) + _("The request has been refused. The validation process is now over."), subtype="refused", context=context) class resource_calendar_leaves(osv.osv): diff --git a/addons/hr_holidays/hr_holidays_data.xml b/addons/hr_holidays/hr_holidays_data.xml index 3b927b60419..ad337b72c62 100644 --- a/addons/hr_holidays/hr_holidays_data.xml +++ b/addons/hr_holidays/hr_holidays_data.xml @@ -55,26 +55,12 @@ Once validated, they are visible in the employee's calendar. HR officers can def
                    - - submitted - - - - - pending - - - - - double validated + + approved - - closed - - - - cancelled + + refused diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 578ebde9162..99d522703d3 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -475,12 +475,12 @@ class hr_applicant(base_stage, osv.Model): self.message_post(cr, uid, [applicant.id], body=message, subtype="closed", context=context) else: message = _("Applicant has been hired.") - self.message_post(cr, uid, [applicant.id], body=message, subtype="closed", context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype="hired", context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): msg = 'Applicant refused.' - return self.message_post(cr, uid, ids, body=msg, subtype="cancelled", context=context) + return self.message_post(cr, uid, ids, body=msg, subtype="refused", context=context) def case_reset_send_note(self, cr, uid, ids, context=None): message =_("Applicant has been set as new.") diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml index a567489751a..818b5f5adef 100644 --- a/addons/hr_recruitment/hr_recruitment_data.xml +++ b/addons/hr_recruitment/hr_recruitment_data.xml @@ -467,12 +467,12 @@ You can automatically receive job application though an email gateway, see the H - - closed + + hired - - cancelled + + refused From 10313331e8f10c148bb9acc602d34822d4bbbae2 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Sep 2012 15:26:49 +0530 Subject: [PATCH 167/726] [IMP] make chnages into subtype data in hr bzr revid: rma@tinyerp.com-20120904095649-ye94bntdm8ia5jrd --- addons/hr_recruitment/hr_recruitment.py | 2 +- addons/hr_recruitment/hr_recruitment_data.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 99d522703d3..2ff594aa820 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -472,7 +472,7 @@ class hr_applicant(base_stage, osv.Model): for applicant in self.browse(cr, uid, ids, context=context): if applicant.emp_id: message = _("Applicant has been hired and created as an employee.") - self.message_post(cr, uid, [applicant.id], body=message, subtype="closed", context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype="hired", context=context) else: message = _("Applicant has been hired.") self.message_post(cr, uid, [applicant.id], body=message, subtype="hired", context=context) diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml index 818b5f5adef..30ff9118584 100644 --- a/addons/hr_recruitment/hr_recruitment_data.xml +++ b/addons/hr_recruitment/hr_recruitment_data.xml @@ -471,7 +471,7 @@ You can automatically receive job application though an email gateway, see the H hired - + refused From d90d78171bb257cc4c65ca935d3f43814e31de67 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Sep 2012 18:34:23 +0530 Subject: [PATCH 168/726] [IMP] make changes into the subtype data for project module bzr revid: rma@tinyerp.com-20120904130423-928mhaatxuxfbwi4 --- addons/base_status/base_stage.py | 6 +++--- addons/project_issue/project_issue.py | 2 +- addons/project_issue/project_issue_data.xml | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 26afe548217..fdbc41cd8ac 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -401,13 +401,13 @@ class base_stage(object): def case_close_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=msg, context=context) + self.message_post(cr, uid, [id], body=msg, subtype="closed", context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): for id in ids: - msg = _('%s has been canceled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=msg, context=context) + msg = _('%s has been cancelled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) + self.message_post(cr, uid, [id], body=msg, subtype="cancelled", context=context) return True def case_pending_send_note(self, cr, uid, ids, context=None): diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 52bb2d2d687..833c7dbb460 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -508,7 +508,7 @@ class project_issue(base_stage, osv.osv): def convert_to_task_send_note(self, cr, uid, ids, context=None): message = _("Project issue converted to task.") - return self.message_post(cr, uid, ids, body=message, subtype="converted", context=context) + return self.message_post(cr, uid, ids, body=message, context=context) def create_send_note(self, cr, uid, ids, context=None): message = _("Project issue created.") diff --git a/addons/project_issue/project_issue_data.xml b/addons/project_issue/project_issue_data.xml index 2501bd821d2..6ee704c6b39 100644 --- a/addons/project_issue/project_issue_data.xml +++ b/addons/project_issue/project_issue_data.xml @@ -42,11 +42,15 @@ - - converted + + cancelled + + closed + + From ef747c7143eb0ce04d505dc1c24eae0d8b83f688 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Wed, 5 Sep 2012 11:00:31 +0530 Subject: [PATCH 169/726] [IMP]improve test case bzr revid: sgo@tinyerp.com-20120905053031-dqtcfyr1na9j7zpk --- addons/mail/tests/test_mail.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index bc8a0e5c085..45583d46fa3 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -566,10 +566,10 @@ class test_mail(common.TransactionCase): _mail_bodyalt2 = 'Pigs rules\nAdmin\n' filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)]) # Post comment with body and subject, comment preference - msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, msg_type='comment',subtype='email') + msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype='email') notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)]) self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall") # New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message - msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, msg_type='email', subtype='other') + msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other') notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)]) self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall") From 3476daf79fad6a05feefd76379c262bfd9d4a4a7 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Wed, 5 Sep 2012 15:01:35 +0530 Subject: [PATCH 170/726] [IMP]Add mail_subtype.rst file in mail bzr revid: fka@tinyerp.com-20120905093135-ydsqq62gnkcifqyv --- addons/mail/doc/index.rst.inc | 1 + addons/mail/doc/mail_subtype.rst | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 addons/mail/doc/mail_subtype.rst diff --git a/addons/mail/doc/index.rst.inc b/addons/mail/doc/index.rst.inc index c4b87cc18f9..4b01d3ec7bd 100644 --- a/addons/mail/doc/index.rst.inc +++ b/addons/mail/doc/index.rst.inc @@ -11,3 +11,4 @@ Mail Module documentation topics mail_needaction_howto mail_partner mail_state + mail_subtype diff --git a/addons/mail/doc/mail_subtype.rst b/addons/mail/doc/mail_subtype.rst new file mode 100644 index 00000000000..e63b67936cd --- /dev/null +++ b/addons/mail/doc/mail_subtype.rst @@ -0,0 +1,70 @@ +.. _mail_message_subtype: + +OpenChatter Pi (3.1415): Message Subtype +======================================== + + To overcome the problems of crowdy walls in system notification, We have added features of **Message Subtype** in mail. + +mail.message.subtype +++++++++++++++++++++ +``mail.message.subtype`` has following fields: + + - ``Name``: fields.char(' Message Subtype ', size = 128,required = True,help = 'Subtype Of Message'), + - ``model_ids``: fields.many2many('ir.model','mail_message_subtyp_message_rel','message_subtype_id', 'model_id', 'Model',help = "link some subtypes to several models, for projet/task"), + - ``default``: fields.boolean('Default', help = "When subscribing to the document, users will receive by default messages related to this subtype unless they uncheck this subtype"), + +mail.followers +++++++++++++++ + +In ``mail.followers`` we have added additional many2many field subtype ids : + + - ``subtype_ids``: fields.many2many('mail.message.subtype','mail_message_subtyp_rel','subscription_id', 'subtype_id', 'Subtype',help = "linking some subscription to several subtype for projet/task") + +mail.message +++++++++++++ + +In mail_message we have added additional field subtype_id which Indicates the Type of Message + + - ``subtype_id``: fields.many2one('mail.message.subtype', 'Subtype') + +mail.thread ++++++++++++ + + - In **message_post** method add the *subtype_id* field as parameter and set as default subtype 'Other'. + + def message_post(self, cr, uid, thread_id, body='', subject=False, msg_type='notification', parent_id=False, attachments=None, subtype='other', context=None, ``**kwargs``): + + - In **message_subscribe** method add the *subtype_ids* field as parameter.In this method if subtype_ids is None, it fatch the default true subtypes in mail.message.subtypes otherwise pass selected subtypes. + For update subtypes call **message_subscribe_udpate_subtypes** method + + def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None): + + - Add **message_subscribe_udpate_subtypes** method to update the subtype_ids in followers. + + def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None): + followers_obj = self.pool.get('mail.followers') + followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) + +For Each Addons: +++++++++++++++++ + + - Add data of subtypes for each addons module. + - Add subtype field as parameter in **message_post** Method for each addons module. + +How It Works: ++++++++++++++ + + - In addons module when we Follow a Perticular document It display under the followers button. + - In sybtypes there are 3 default subtypes for each addons + 1) Email + 2) Comment + 3) Other + - In document display a default subtypes(which are true) related a perticular model_ids wise. + + Example:- + If I have open crm.lead, It display only subtypes of crm.lead + + - When we select subtype it update subtype_ids(which are checked) in mail.follower where match res_model & res_id of the current documents. + - when message created update subtype_id of that message in mail.message. + - In Feeds display only those notifications of documents which subtypes are selected From dc331c76eeeba1c4f1dadb07a2c6ccbdef28ff6f Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Wed, 5 Sep 2012 16:01:36 +0530 Subject: [PATCH 171/726] [IMP] If not journal_id then return {} and parent is removed. bzr revid: bth@tinyerp.com-20120905103136-pp94j3xnb64c2edo --- addons/account/account_bank_statement.py | 2 ++ .../account_bank_statement_view.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 8df291a98d1..85826e13b69 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -455,6 +455,8 @@ class account_bank_statement(osv.osv): return res and res[0] or 0.0 def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None): + if not journal_id: + return {} balance_start = self._compute_balance_end_real(cr, uid, journal_id, context=context) journal_data = self.pool.get('account.journal').read(cr, uid, journal_id, ['default_debit_account_id', 'company_id'], context=context) diff --git a/addons/account_bank_statement_extensions/account_bank_statement_view.xml b/addons/account_bank_statement_extensions/account_bank_statement_view.xml index 30b2778817c..1c076426752 100644 --- a/addons/account_bank_statement_extensions/account_bank_statement_view.xml +++ b/addons/account_bank_statement_extensions/account_bank_statement_view.xml @@ -76,7 +76,7 @@ - + @@ -100,7 +100,7 @@ - + From ca9c79727541fbf87f316906887e920e79b9550c Mon Sep 17 00:00:00 2001 From: Amit Parik Date: Wed, 5 Sep 2012 17:03:13 +0530 Subject: [PATCH 172/726] [FIX]:project_timesheet impossible to edit task work bzr revid: pja@tinyerp.com-20120905113313-c2cbi37xqr6mnvrc --- addons/project_timesheet/project_timesheet.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py index 1e50848201c..12d1eedbeb2 100644 --- a/addons/project_timesheet/project_timesheet.py +++ b/addons/project_timesheet/project_timesheet.py @@ -166,10 +166,7 @@ class project_work(osv.osv): vals_line['name'] = '%s: %s' % (tools.ustr(task.task_id.name), tools.ustr(vals['name']) or '/') if 'user_id' in vals: vals_line['user_id'] = vals['user_id'] - result = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id)) - for fld in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'): - if result.get(fld, False): - vals_line[fld] = result[fld] + if 'date' in vals: vals_line['date'] = vals['date'][:10] @@ -177,7 +174,10 @@ class project_work(osv.osv): default_uom = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id vals_line['unit_amount'] = vals['hours'] prod_id = vals_line.get('product_id', line_id.product_id.id) # False may be set - + result = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id)) + for fld in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'): + if result.get(fld, False): + vals_line[fld] = result[fld] if result.get('product_uom_id',False) and (not result['product_uom_id'] == default_uom): vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, default_uom, vals['hours'], result['product_uom_id']) From d3edae5084b9c4a0a60fa0992c7e517ceb0b3bc7 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 12:25:03 +0530 Subject: [PATCH 173/726] [IMP]:improved yml bzr revid: apa@tinyerp.com-20120906065503-h8rziczo7ri31z3o --- addons/crm/test/process/crm_message_subtype.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index 705d3cc2fc4..ee78553c913 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -9,7 +9,7 @@ - I have add the sub_type name email with default true - - !record {model: mail.message.subtype, id: mail_subtype_lead_email }: + !record {model: mail.message.subtype, id: mail.mail_subtype_email }: name: email model_ids: - crm.model_crm_lead @@ -17,7 +17,7 @@ - I have add the sub_type name comment with default true - - !record {model: mail.message.subtype, id: mail_subtype_lead_comment }: + !record {model: mail.message.subtype, id: mail.mail_subtype_comment }: name: comment model_ids: - crm.model_crm_lead From c028143bcf6e33592ff4c344ff990285ad48a178 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 12:33:34 +0530 Subject: [PATCH 174/726] [IMP]:improved yml bzr revid: apa@tinyerp.com-20120906070334-bf4fvtr3kz055qfh --- addons/crm/crm_lead_data.xml | 2 +- addons/crm/test/process/crm_message_subtype.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 6f6562657ce..168aa62f714 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -160,7 +160,7 @@ - + won diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index ee78553c913..6c0038a7fb8 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -1,7 +1,7 @@ - I have add the sub_type name other with default false - - !record {model: mail.message.subtype, id: mail_subtype_lead_won }: + !record {model: mail.message.subtype, id: mail.mail_subtype_won }: name: won model_ids: - crm.model_crm_lead From 87bb5e31bff85fd3d5abe685d5271970c53c403b Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 12:35:09 +0530 Subject: [PATCH 175/726] [IMP]:improved yml bzr revid: apa@tinyerp.com-20120906070509-u7ueba94sr10dqcg --- addons/crm/test/process/crm_message_subtype.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index 6c0038a7fb8..3dd042c1279 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -27,7 +27,7 @@ - !python {model: mail.followers}: | ids = self.search(cr, uid, [('res_model', '=', 'crm.lead'),('res_id', '=', ref('crm_case_1'))]) - self.write(cr, uid, ids, {'subtype_ids': [(6,0,[ref('mail_subtype_lead_won')])]}) + self.write(cr, uid, ids, {'subtype_ids': [(6,0,[ref('mail.mail_subtype_won')])]}) - I have change the lead into mark won - @@ -43,6 +43,6 @@ I have check the subtype as won in feeds - !python {model: mail.followers}: | - followers_ids =self.search(cr, uid, [('res_model', '=','crm.lead'),('res_id', '=', ref('crm_case_1')),('subtype_ids', 'in',[ref('mail_subtype_lead_won')])]) + followers_ids =self.search(cr, uid, [('res_model', '=','crm.lead'),('res_id', '=', ref('crm_case_1')),('subtype_ids', 'in',[ref('mail.mail_subtype_won')])]) if len(followers_ids): assert followers_ids, 'lead is in won' From 70c1c3df658c38e477108c40c8344bd0d967cd1e Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 12:38:01 +0530 Subject: [PATCH 176/726] [IMP]:hide subtype when unfollowing bzr revid: apa@tinyerp.com-20120906070801-9fulnfblrrdxhetx --- addons/mail/static/src/js/mail_followers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 5d7b2ec5116..90318664474 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -95,7 +95,7 @@ openerp_mail_followers = function(session, mail) { else { this.$el.find('button.oe_mail_button_follow').show(); this.$el.find('button.oe_mail_button_unfollow').hide(); - // this.$el.find('ul.oe_mail_recthread_subtype').hide() + this.$el.find('ul.oe_mail_recthread_subtype').hide() } }, update_subtype: function (){ From 330abd29996e4b439c0d7cd59b9ace89fc7119f8 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 15:07:54 +0530 Subject: [PATCH 177/726] [IMP]:improved indentation bzr revid: apa@tinyerp.com-20120906093754-gvly9tnpbc6mzhxs --- addons/mrp_repair/mrp_repair_data.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/mrp_repair/mrp_repair_data.xml b/addons/mrp_repair/mrp_repair_data.xml index 337a4113382..b45b7ec3105 100644 --- a/addons/mrp_repair/mrp_repair_data.xml +++ b/addons/mrp_repair/mrp_repair_data.xml @@ -1,7 +1,6 @@ - - + new @@ -44,5 +43,5 @@ - + From 4707ee56a9e6f2d5b4af389a1adba8fd83f0dac4 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 6 Sep 2012 15:11:23 +0530 Subject: [PATCH 178/726] [IMP]add context to the method bzr revid: sgo@tinyerp.com-20120906094123-ua4zxhot0z3wgd7g --- addons/mail/mail_message.py | 2 +- addons/mail/mail_thread.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 3ef731b766b..be1fbe78176 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -335,7 +335,7 @@ class mail_message(osv.Model): missing_follow_ids = [] if message.subtype_id: for p_id in missing_notified: - follow_ids = followers_obj.search(cr, uid, [('partner_id','=',p_id),('subtype_ids','in',[message.subtype_id.id]),('res_model','=',message.model),('res_id','=',message.res_id)]) + follow_ids = followers_obj.search(cr, uid, [('partner_id','=',p_id),('subtype_ids','in',[message.subtype_id.id]),('res_model','=',message.model),('res_id','=',message.res_id)], context=context) if follow_ids and len(follow_ids): missing_follow_ids.append(p_id) message.write({'partner_ids': [(4, p_id) for p_id in missing_follow_ids]}) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 7fc6c79bd9a..4d627712742 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -600,9 +600,9 @@ class mail_thread(osv.AbstractModel): values = kwargs subtype_obj = self.pool.get('mail.message.subtype') if subtype: - subtypes = subtype_obj.name_search(cr, uid, subtype) + subtypes = subtype_obj.name_search(cr, uid, subtype,context=context) if len(subtypes): - subtype_browse = subtype_obj.browse(cr, uid, subtypes[0][0]) + subtype_browse = subtype_obj.browse(cr, uid, subtypes[0][0],context=context) if self._name in [model.model for model in subtype_browse.model_ids]: values['subtype_id']=subtype_browse.id values.update({ @@ -636,7 +636,7 @@ class mail_thread(osv.AbstractModel): self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) if not subtype_ids: subtype_obj = self.pool.get('mail.message.subtype') - subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)]) + subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)],context=context) if subtype_ids: self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context) if context and context.get('read_back'): @@ -690,7 +690,7 @@ class mail_thread(osv.AbstractModel): def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None): followers_obj = self.pool.get('mail.followers') - followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From f36dd4c891710bb3ddb6e097f80ef0b9b6c26134 Mon Sep 17 00:00:00 2001 From: "Amit Patel (OpenERP)" Date: Thu, 6 Sep 2012 16:29:14 +0530 Subject: [PATCH 179/726] [IMP]:improved test case bzr revid: apa@tinyerp.com-20120906105914-iwoi15ghgtibt2lr --- addons/mail/data/mail_data.xml | 5 ++++- addons/mail/mail_thread.py | 2 +- addons/mail/tests/test_mail.py | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index b241cb095de..80aff038dac 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -15,13 +15,16 @@ other - + + email + comment + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 4d627712742..42581654ace 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -562,7 +562,7 @@ class mail_thread(osv.AbstractModel): self.message_post(cr, uid, [id], message, context=context) def message_post(self, cr, uid, thread_id, body='', subject=False, - type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs): + type='notification', parent_id=False, attachments=None, subtype='comment', context=None, **kwargs): """ Post a new message in an existing thread, returning the new mail.message ID. Extra keyword arguments will be used as default column values for the new mail.message record. diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index a8c1d6b7cf1..8cf0e25ecbb 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -616,9 +616,7 @@ class test_mail(common.TransactionCase): # 0 - Admin p_a_id = user_admin.partner_id.id # Subscribe #1, - self.mail_group_model_id = self.ir_model.search(cr, uid, [('model','=', 'mail.group')])[0] - subtype_ids = self.mail_message_subtype.search(cr, uid, []) - self.mail_message_subtype.write(cr,uid,subtype_ids,{'model_ids':[(4,self.mail_group_model_id )]}) + group_pigs.message_subscribe_users([uid]) # Mail data From 6977a136498ccd320f5dbcc0caa9e476db5ada86 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 7 Sep 2012 17:12:16 +0530 Subject: [PATCH 180/726] [IMP]resolve error bzr revid: sgo@tinyerp.com-20120907114216-5qbzq1y80ut9d6mx --- addons/mail/mail_message_subtype.xml | 9 +++++++++ addons/mail/static/src/js/mail_followers.js | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_message_subtype.xml b/addons/mail/mail_message_subtype.xml index 8de3224470f..0bfdc2cad95 100644 --- a/addons/mail/mail_message_subtype.xml +++ b/addons/mail/mail_message_subtype.xml @@ -47,6 +47,15 @@ mail.message.subtype form tree,form + +

                    + Click to create a message subtype. +

                    + OpenERP's message subtype allows to ease and fasten the + subtype which helps to decrease over crowdy wall comments which displays + only those. +

                    +
                    Date: Fri, 7 Sep 2012 17:42:58 +0530 Subject: [PATCH 181/726] [IMP]improve code bzr revid: sgo@tinyerp.com-20120907121258-r48mymwh9yvxlrqi --- addons/mail/static/src/js/mail_followers.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 53f2117fa04..c2d4f31c159 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -117,8 +117,9 @@ openerp_mail_followers = function(session, mail) { follower_read.then(function (follower_record){ if(follower_record.length != 0){ _(follower_record[0].subtype_ids).each(function (subtype_id){ - if(self.$el.find('.oe_msg_subtype_check[id=' + subtype_id + ']')[0]){ - self.$el.find('.oe_msg_subtype_check[id=' + subtype_id + ']')[0].checked=true} + var subtype_check = self.$el.find('.oe_msg_subtype_check[id=' + subtype_id + ']') + if(subtype_check.length > 0){ + subtype_check[0].checked=true} }); } }) From 741bbaa9f457577b25d8f6007b6aae34aedf2840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 7 Sep 2012 18:09:20 +0200 Subject: [PATCH 182/726] [WIP] mail_message.message_read(): WIP about having correct expandables. Will be updated next week. bzr revid: tde@openerp.com-20120907160920-4ijs93y9ogp39xma --- addons/mail/mail_message.py | 59 ++++++++++++++++++++++++---------- addons/mail/res_partner.py | 1 - addons/mail/tests/test_mail.py | 13 ++++---- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 18a88bb0b61..90ccc8a2f24 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -167,7 +167,24 @@ class mail_message(osv.Model): 'child_ids': [], } - def message_read_tree_flatten(self, cr, uid, messages, current_level, level, context=None): + def message_read_tree_get_expandable(self, cr, uid, parent_message, last_message, domain=[], current_level=0, level=0, context=None): + """ . """ + base_domain = [('id', '<', last_message['id'])] + if parent_message and current_level < level: + base_domain += [('parent_id', '=', parent_message['id'])] + elif parent_message: + base_domain += [('id', 'child_od', parent_message['id'])] + if domain: + base_domain += domain + extension = { 'type': 'expandable', + 'domain': base_domain, + 'thread_level': current_level, + 'context': context, + 'id': -1, + } + return extension + + def message_read_tree_flatten(self, cr, uid, parent_message, messages, current_level, level, domain=[], context=None): """ Given a tree with several roots of following structure : [ {'id': 1, 'child_ids': [ {'id': 11, 'child_ids': [...] },], @@ -186,28 +203,36 @@ class mail_message(osv.Model): child_ids = msg_dict.pop('child_ids', []) msg_dict['child_ids'] = [] return [msg_dict] + child_ids - # return sorted([msg_dict] + child_ids, key=itemgetter('id'), reverse=True) context = context or {} # Depth-first flattening for message in messages: if message.get('type') == 'expandable': continue - message['child_ids'] = self.message_read_tree_flatten(cr, uid, message['child_ids'], current_level + 1, level, context=context) + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], current_level + 1, level, domain, context=context) # Flatten if above maximum depth if current_level < level: return_list = messages else: - return_list = [] - for message in messages: - for flat_message in _flatten(message): - return_list.append(flat_message) - return sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) + return_list = [flat_message for message in messages for flat_message in _flatten(message)] + # Add expandable + return_list = sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) + if current_level <= level: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) + print 'expandable', expandable + return return_list - def message_read(self, cr, uid, ids=False, domain=[], thread_level=0, limit=None, context=None): - """ If IDs are provided, fetch these records. Otherwise use the domain - to fetch the matching records. - After having fetched the records provided by IDs, it will fetch the - parents to have well-formed threads. + def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, tree_parent_id=False): + """ Read messages from mail.message, and get back a structured tree + of messages to be displayed as discussion threads. If IDs is set, + fetch these records. Otherwise use the domain to fetch messages. + After having fetch messages, their parents will be added to obtain + well formed threads. + + :param domain: optional domain for searching ids + :param level: level of threads to display, 0 being flat + :param limit: number of messages to fetch + :param tree_parent_id: if parent_id reached, stop searching for + further parents :return list: list of trees of messages """ limit = limit or self._message_read_limit @@ -221,8 +246,8 @@ class mail_message(osv.Model): for msg in messages: if len(result) < (limit - 1): record = self._message_dict_get(cr, uid, msg, context=context) - if thread_level and msg.parent_id: - while msg.parent_id: + if level and msg.parent_id: + while msg.parent_id != tree_parent_id: if msg.parent_id.id in tree: record_parent = tree[msg.parent_id.id] else: @@ -241,14 +266,14 @@ class mail_message(osv.Model): 'type': 'expandable', 'domain': [('id', '<=', msg.id)] + domain, 'context': context, - 'thread_level': thread_level, # should be improve accodting to level of records + 'thread_level': level, # should be improve accodting to level of records 'id': -1, }) break # Flatten the result if thread_level > 0: - result = self.message_read_tree_flatten(cr, uid, result, 0, thread_level, context=context) + result = self.message_read_tree_flatten(cr, uid, None, result, 0, thread_level, domain, context=context) return result #------------------------------------------------------ diff --git a/addons/mail/res_partner.py b/addons/mail/res_partner.py index 2988cee3d9c..4a6f98fa31d 100644 --- a/addons/mail/res_partner.py +++ b/addons/mail/res_partner.py @@ -41,5 +41,4 @@ class res_partner_mail(osv.Model): 'notification_email_send': lambda *args: 'comment' } - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index f45745f31dc..1f65c38f755 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -459,13 +459,13 @@ class test_mail(common.TransactionCase): cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) def _compare_structures(struct1, struct2, n=0): - # print '%scompare structure' % ('\t' * n) + print '%scompare structure' % ('\t' * n) self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect') for x in range(len(struct1)): - # print '%s' % ('\t' * n), struct1[x]['id'], struct2[x]['id'], struct1[x].get('subject') or '' + print '%s' % ('\t' * n), struct1[x]['id'], struct2[x]['id'], struct1[x].get('subject') or '' self.assertEqual(struct1[x]['id'], struct2[x]['id'], 'message_read failure %s' % struct1[x].get('subject')) _compare_structures(struct1[x]['child_ids'], struct2[x]['child_ids'], n + 1) - # print '%send compare' % ('\t' * n) + print '%send compare' % ('\t' * n) # ---------------------------------------- # CASE1: Flattening test @@ -490,7 +490,8 @@ class test_mail(common.TransactionCase): ]}, ] # Test: completely flat - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 0) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 0, [('type', 'in', 'borderlands')]) + _compare_structures(new_tree, new_tree) self.assertEqual(len(new_tree), 10, 'message_read_tree_flatten wrong in flat') # Test: 1 thread level tree_test = [{'id': 2, 'child_ids': [ @@ -502,10 +503,10 @@ class test_mail(common.TransactionCase): {'id': 4, 'child_ids': []}, {'id': 3, 'child_ids': []}, ]}, ] - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 1) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 1, [('type', 'in', 'borderlands')]) _compare_structures(new_tree, tree_test) # Test: 2 thread levels - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, copy.deepcopy(tree), 0, 2) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 2, [('type', 'in', 'borderlands')]) _compare_structures(new_tree, tree) # ---------------------------------------- From 004b9c9a849f2f92e3ed4eb192531780e15a0a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 9 Sep 2012 13:45:15 +0200 Subject: [PATCH 183/726] create invoice: changing journal changes company too lp bug: https://launchpad.net/bugs/1047884 fixed bzr revid: stephane.bidoul@acsone.eu-20120909114515-mbilk7jv2aj1mn9x --- addons/account/account_invoice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 15027b7a8f6..e925e87c136 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -503,8 +503,10 @@ class account_invoice(osv.osv): if journal_id: journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context) currency_id = journal.currency and journal.currency.id or journal.company_id.currency_id.id + company_id = journal.company_id.id result = {'value': { 'currency_id': currency_id, + 'company_id': company_id, } } return result From 17edcf06301179bd9d7a7d05458e7d00c67a1d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 9 Sep 2012 14:42:59 +0200 Subject: [PATCH 184/726] select account and taxes for the invoice's company instead of the user's default company when changing product or account This partially fixes lp:1048213 since the default account proposed when creating a new invoice line (in trunk only) is still from the user's company. lp bug: https://launchpad.net/bugs/1048213 fixed bzr revid: stephane.bidoul@acsone.eu-20120909124259-df6qo743sfogltf9 --- addons/account/account_invoice.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index e925e87c136..cd77b202e0e 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1365,7 +1365,10 @@ class account_invoice_line(osv.osv): 'partner_id': fields.related('invoice_id','partner_id',type='many2one',relation='res.partner',string='Partner',store=True) } - def _default_account_id(self, cr, uid, ids, context=None): + def _default_account_id(self, cr, uid, context=None): + # XXX this gets the default account for the user's company, + # it should get the default account for the invoice's company + # however, the invoice's company does not reach this point prop = self.pool.get('ir.property').get(cr, uid, 'property_account_income_categ', 'product.category', context=context) return prop and prop.id or False @@ -1395,7 +1398,7 @@ class account_invoice_line(osv.osv): context = {} company_id = company_id if company_id != None else context.get('company_id',False) context = dict(context) - context.update({'company_id': company_id}) + context.update({'company_id': company_id, 'force_company': company_id}) if not partner_id: raise osv.except_osv(_('No Partner Defined !'),_("You must first select a partner !") ) if not product: @@ -1550,12 +1553,14 @@ class account_invoice_line(osv.osv): def onchange_account_id(self, cr, uid, ids, product_id, partner_id, inv_type, fposition_id, account_id): if not account_id: return {} - taxes = self.pool.get('account.account').browse(cr, uid, account_id).tax_ids + account = self.pool.get('account.account').browse(cr, uid, account_id) + taxes = account.tax_ids fpos = fposition_id and self.pool.get('account.fiscal.position').browse(cr, uid, fposition_id) or False tax_ids = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes) product_change_result = self.product_id_change(cr, uid, ids, product_id, False, type=inv_type, - partner_id=partner_id, fposition_id=fposition_id) + partner_id=partner_id, fposition_id=fposition_id, + company_id=account.company_id.id) unique_tax_ids = set(tax_ids) if product_change_result and 'value' in product_change_result and 'invoice_line_tax_id' in product_change_result['value']: unique_tax_ids |= set(product_change_result['value']['invoice_line_tax_id']) From 4deb1f84e7eb7f6cf23bc6dfe61c1d92b968d82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 9 Sep 2012 17:24:38 +0200 Subject: [PATCH 185/726] hr_timesheet_invoice, bill task work: use the analytic account company for the generated invoice_cost_create This makes life much easiers for people generating billings for several companies. lp bug: https://launchpad.net/bugs/1047826 fixed bzr revid: stephane.bidoul@acsone.eu-20120909152438-qax5pv4ij76asmbv --- .../wizard/hr_timesheet_invoice_create.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py index 76314e1986a..e33e88203f8 100644 --- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py +++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py @@ -79,17 +79,24 @@ class account_analytic_line(osv.osv): curr_invoice = { 'name': time.strftime('%d/%m/%Y')+' - '+account.name, 'partner_id': account.partner_id.id, + 'company_id': account.company_id.id, 'payment_term': partner.property_payment_term.id or False, 'account_id': partner.property_account_receivable.id, 'currency_id': account.pricelist_id.currency_id.id, 'date_due': date_due, 'fiscal_position': account.partner_id.property_account_position.id } - last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context) - invoices.append(last_invoice) - + context2 = context.copy() context2['lang'] = partner.lang + # set company_id in context, so the correct default journal will be selected + context2['force_company'] = curr_invoice['company_id'] + # set force_company in context so the correct product properties are selected (eg. income account) + context2['company_id'] = curr_invoice['company_id'] + + last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2) + invoices.append(last_invoice) + cr.execute("SELECT product_id, to_invoice, sum(unit_amount), product_uom_id, name " \ "FROM account_analytic_line as line " \ "WHERE account_id = %s " \ From 38dfccaaa08d4ee8e73e88cc17430e95313591e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 9 Sep 2012 18:59:19 +0200 Subject: [PATCH 186/726] hr_timesheet_invoice: in invoice task work, use the account default tax if the product has no taxes defined lp bug: https://launchpad.net/bugs/1048305 fixed bzr revid: stephane.bidoul@acsone.eu-20120909165919-xgxu45ugq3944gvu --- .../wizard/hr_timesheet_invoice_create.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py index e33e88203f8..32ae652ca3d 100644 --- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py +++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py @@ -122,11 +122,11 @@ class account_analytic_line(osv.osv): else: price = 0.0 - taxes = product.taxes_id - tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes) - account_id = product.product_tmpl_id.property_account_income.id or product.categ_id.property_account_income_categ.id - if not account_id: + general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ + if not general_account: raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name) + taxes = product.taxes_id or general_account.tax_ids + tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes) curr_line = { 'price_unit': price, 'quantity': qty, @@ -137,7 +137,7 @@ class account_analytic_line(osv.osv): 'product_id': product_id, 'invoice_line_tax_id': [(6,0,tax)], 'uos_id': uom, - 'account_id': account_id, + 'account_id': general_account.id, 'account_analytic_id': account.id, } From 5cf330f39a23157caa50d475add761ff93109f99 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Mon, 10 Sep 2012 11:19:03 +0530 Subject: [PATCH 187/726] [IMP]add help on subtype name bzr revid: sgo@tinyerp.com-20120910054903-22sveyi971arsl39 --- addons/mail/mail_message_subtype.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py index ab41c83ed61..2330e34e1d3 100644 --- a/addons/mail/mail_message_subtype.py +++ b/addons/mail/mail_message_subtype.py @@ -27,8 +27,8 @@ class mail_message_subtype(osv.osv): _name = 'mail.message.subtype' _description = 'mail_message_subtype' _columns = { - 'name': fields.char(' Message Subtype ', size = 128, - required = True, help = 'Subtype Of Message'), + 'name': fields.char('Message Subtype ', size = 128, + required = True, help = 'Message subtype, gives a more precise type on the message, especially for system notifications. For example, it can be a notification related to a new record (New), or to a stage change in a process (Stage change). Message subtypes allow to precisely tune the notifications the user want to receive on its wall.'), 'model_ids': fields.many2many('ir.model', 'mail_message_subtyp_message_rel', 'message_subtype_id', 'model_id', 'Model', From dfa14420d212911bb5f87af19231a848c59cab07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 11 Sep 2012 14:01:17 +0200 Subject: [PATCH 188/726] [WIP] mail_message: continued work on message_read and expandables. bzr revid: tde@openerp.com-20120911120117-xeeercvglfwq3c9e --- addons/mail/mail_message.py | 69 +++++++++++++++---------------- addons/mail/static/src/js/mail.js | 2 +- addons/mail/tests/test_mail.py | 37 +++++++++-------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 90ccc8a2f24..230199569f4 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -147,6 +147,7 @@ class mail_message(osv.Model): def _message_dict_get(self, cr, uid, msg, context=None): """ Return a dict representation of the message browse record. """ + child_nbr = len(msg.child_ids) attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)] author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0] author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0] @@ -165,6 +166,7 @@ class mail_message(osv.Model): 'author_user_id': author_user_id, 'partner_ids': partner_ids, 'child_ids': [], + 'child_nbr': child_nbr, } def message_read_tree_get_expandable(self, cr, uid, parent_message, last_message, domain=[], current_level=0, level=0, context=None): @@ -173,7 +175,7 @@ class mail_message(osv.Model): if parent_message and current_level < level: base_domain += [('parent_id', '=', parent_message['id'])] elif parent_message: - base_domain += [('id', 'child_od', parent_message['id'])] + base_domain += [('id', 'child_of', parent_message['id'])] if domain: base_domain += domain extension = { 'type': 'expandable', @@ -184,7 +186,7 @@ class mail_message(osv.Model): } return extension - def message_read_tree_flatten(self, cr, uid, parent_message, messages, current_level, level, domain=[], context=None): + def message_read_tree_flatten(self, cr, uid, parent_message, messages, domain=[], level=0, current_level=0, context=None, limit=None): """ Given a tree with several roots of following structure : [ {'id': 1, 'child_ids': [ {'id': 11, 'child_ids': [...] },], @@ -204,11 +206,14 @@ class mail_message(osv.Model): msg_dict['child_ids'] = [] return [msg_dict] + child_ids context = context or {} + limit = limit or self._message_read_limit # Depth-first flattening for message in messages: if message.get('type') == 'expandable': continue - message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], current_level + 1, level, domain, context=context) + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], domain, level, current_level + 1, context=context) + for child in message['child_ids']: + message['child_nbr'] += child['child_nbr'] # Flatten if above maximum depth if current_level < level: return_list = messages @@ -216,12 +221,17 @@ class mail_message(osv.Model): return_list = [flat_message for message in messages for flat_message in _flatten(message)] # Add expandable return_list = sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) - if current_level <= level: + if current_level == 0: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) + if len(return_list) >= limit: + print 'we need an expandable here' + print 'expandable', expandable + elif current_level <= level: expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) print 'expandable', expandable return return_list - def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, tree_parent_id=False): + def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, parent_id=False): """ Read messages from mail.message, and get back a structured tree of messages to be displayed as discussion threads. If IDs is set, fetch these records. Otherwise use the domain to fetch messages. @@ -231,7 +241,7 @@ class mail_message(osv.Model): :param domain: optional domain for searching ids :param level: level of threads to display, 0 being flat :param limit: number of messages to fetch - :param tree_parent_id: if parent_id reached, stop searching for + :param parent_id: if parent_id reached, stop searching for further parents :return list: list of trees of messages """ @@ -241,39 +251,28 @@ class mail_message(osv.Model): ids = self.search(cr, uid, domain, context=context, limit=limit) messages = self.browse(cr, uid, ids, context=context) + # key: ID, value: record + tree = {} result = [] - tree = {} # key: ID, value: record for msg in messages: - if len(result) < (limit - 1): - record = self._message_dict_get(cr, uid, msg, context=context) - if level and msg.parent_id: - while msg.parent_id != tree_parent_id: - if msg.parent_id.id in tree: - record_parent = tree[msg.parent_id.id] - else: - record_parent = self._message_dict_get(cr, uid, msg.parent_id, context=context) - if msg.parent_id.parent_id: - tree[msg.parent_id.id] = record_parent - if record['id'] not in [x['id'] for x in record_parent['child_ids']]: - record_parent['child_ids'].append(record) - record = record_parent - msg = msg.parent_id - if msg.id not in tree: - result.append(record) - tree[msg.id] = record - else: - result.append({ - 'type': 'expandable', - 'domain': [('id', '<=', msg.id)] + domain, - 'context': context, - 'thread_level': level, # should be improve accodting to level of records - 'id': -1, - }) - break + record = self._message_dict_get(cr, uid, msg, context=context) + while msg.parent_id and msg.parent_id.id != parent_id: + if msg.parent_id.id in tree: + record_parent = tree[msg.parent_id.id] + else: + record_parent = self._message_dict_get(cr, uid, msg.parent_id, context=context) + if msg.parent_id.parent_id: + tree[msg.parent_id.id] = record_parent + if record['id'] not in [x['id'] for x in record_parent['child_ids']]: + record_parent['child_ids'].append(record) + record = record_parent + msg = msg.parent_id + if msg.id not in tree: + result.append(record) + tree[msg.id] = record # Flatten the result - if thread_level > 0: - result = self.message_read_tree_flatten(cr, uid, None, result, 0, thread_level, domain, context=context) + result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context) return result #------------------------------------------------------ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index c02b81d0c4f..651a2642cc4 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -455,7 +455,7 @@ openerp.mail = function(session) { return this.message_display(this.options.message_data); } return this.ds_message.call('message_read', - [(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, undefined, fetch_context] + [(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, fetch_context] ).then(this.proxy('message_display')); }, diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 1f65c38f755..053e5697207 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -29,7 +29,7 @@ Received: by mail1.openerp.com (Postfix, from userid 10002) From: Sylvie Lelitre Subject: {subject} MIME-Version: 1.0 -Content-Type: multipart/alternative; +Content-Type: multipart/alternative; boundary="----=_Part_4200734_24778174.1344608186754" Date: Fri, 10 Aug 2012 14:16:26 +0000 Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com> @@ -52,9 +52,9 @@ Content-Transfer-Encoding: quoted-printable =20 =20 - +

                    Please call me as soon as possible this afternoon!

                    - +

                    --
                    Sylvie

                    @@ -153,7 +153,7 @@ class test_mail(common.TransactionCase): test_msg_id = '' mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id) self.mail_thread.message_process(cr, uid, None, mail_text) - new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id','=',test_msg_id)])[0]) + new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0]) self.assertEqual(new_mail.body, '\n

                    \nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
                    \n', 'plaintext mail incorrectly parsed') @@ -458,11 +458,12 @@ class test_mail(common.TransactionCase): # It will be updated as soon as we have fixed specs ! cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + def _compare_structures(struct1, struct2, n=0): print '%scompare structure' % ('\t' * n) self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect') for x in range(len(struct1)): - print '%s' % ('\t' * n), struct1[x]['id'], struct2[x]['id'], struct1[x].get('subject') or '' + print '%s' % ('\t' * n), struct1[x]['id'], struct1[x]['child_nbr'], struct2[x]['id'], struct2[x]['child_nbr'], struct1[x].get('subject') or '' self.assertEqual(struct1[x]['id'], struct2[x]['id'], 'message_read failure %s' % struct1[x].get('subject')) _compare_structures(struct1[x]['child_ids'], struct2[x]['child_ids'], n + 1) print '%send compare' % ('\t' * n) @@ -473,24 +474,24 @@ class test_mail(common.TransactionCase): # Create dummy message structure import copy - tree = [{'id': 2, 'child_ids': [ - {'id': 6, 'child_ids': [ - {'id': 8, 'child_ids': []}, + tree = [{'id': 2, 'child_nbr': 1, 'child_ids': [ + {'id': 6, 'child_nbr': 1, 'child_ids': [ + {'id': 8, 'child_nbr': 0, 'child_ids': []}, ]}, ]}, - {'id': 1, 'child_ids':[ - {'id': 7, 'child_ids': [ - {'id': 9, 'child_ids': []}, + {'id': 1, 'child_nbr': 3, 'child_ids':[ + {'id': 7, 'child_nbr': 1, 'child_ids': [ + {'id': 9, 'child_nbr': 0, 'child_ids': []}, ]}, - {'id': 4, 'child_ids': [ - {'id': 10, 'child_ids': []}, - {'id': 5, 'child_ids': []}, + {'id': 4, 'child_nbr': 2, 'child_ids': [ + {'id': 10, 'child_nbr': 0, 'child_ids': []}, + {'id': 5, 'child_nbr': 0, 'child_ids': []}, ]}, - {'id': 3, 'child_ids': []}, + {'id': 3, 'child_nbr': 0, 'child_ids': []}, ]}, ] # Test: completely flat - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 0, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 0) _compare_structures(new_tree, new_tree) self.assertEqual(len(new_tree), 10, 'message_read_tree_flatten wrong in flat') # Test: 1 thread level @@ -503,10 +504,10 @@ class test_mail(common.TransactionCase): {'id': 4, 'child_ids': []}, {'id': 3, 'child_ids': []}, ]}, ] - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 1, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 1) _compare_structures(new_tree, tree_test) # Test: 2 thread levels - new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), 0, 2, [('type', 'in', 'borderlands')]) + new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 2) _compare_structures(new_tree, tree) # ---------------------------------------- From 09ba29883c06d1f1de06c40e89c864c85f53d5c7 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 11 Sep 2012 15:52:54 +0200 Subject: [PATCH 189/726] [FIX] ir.translation: typo in last sync with trunk bzr revid: odo@openerp.com-20120911135254-uqi1s4n8qh0e3d1y --- openerp/addons/base/ir/ir_translation.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 68b413344b2..c8f9cf8e6fe 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -68,7 +68,6 @@ class ir_translation_import_cursor(object): # Note that Postgres will NOT inherit the constraints or indexes # of ir_translation, so this copy will be much faster. - cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), imd_name VARCHAR(128) @@ -77,16 +76,14 @@ class ir_translation_import_cursor(object): def push(self, trans_dict): """Feed a translation, as a dictionary, into the cursor """ - params = dict(trans_dict, - state="translated" if trans_dict['value'] else "to_translate") + params = dict(trans_dict, state="translated" if trans_dict['value'] else "to_translate") self._cr.execute("""INSERT INTO %s (name, lang, res_id, src, type, imd_model, module, imd_name, value, state) - VALUES (%(name)s, %(lang)s, %(res_id)s, %(src)s, %(type)s, %(imd_model)s, %(module)s, %(imd_name)s, %(value)s, %(state)s)""", - params) + VALUES (%%(name)s, %%(lang)s, %%(res_id)s, %%(src)s, %%(type)s, %%(imd_model)s, %%(module)s, %%(imd_name)s, %%(value)s, %%(state)s)""" % self._table_name, + params) def finish(self): """ Transfer the data from the temp table to ir.translation """ - cr = self._cr if self._debug: cr.execute("SELECT count(*) FROM %s" % self._table_name) @@ -129,7 +126,6 @@ class ir_translation_import_cursor(object): """ % (self._parent_table, self._table_name, find_expr)) # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module, state) SELECT name, lang, res_id, src, type, value, module, state FROM %s AS ti From 6f0b0355df2ddc0541afa7510558491921b3e5bb Mon Sep 17 00:00:00 2001 From: Hardik Date: Wed, 12 Sep 2012 11:42:52 +0530 Subject: [PATCH 190/726] [FIX] Survey : traceback when click on answer survey lp bug: https://launchpad.net/bugs/1048954 fixed bzr revid: hsa@tinyerp.com-20120912061252-qul9z1eycawtgu4b --- addons/survey/survey.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/survey/survey.py b/addons/survey/survey.py index dde3130e9c5..8eddab92689 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -145,10 +145,14 @@ class survey(osv.osv): return report def fill_survey(self, cr, uid, ids, context=None): - sur_obj = self.read(cr, uid, ids,['title'], context=context) + sur_obj = self.read(cr, uid, ids,['title', 'page_ids'], context=context) for sur in sur_obj: name = sur['title'] - context.update({'active':False,'survey_id': ids[0]}) + pages = sur['page_ids'] + if not pages: + raise osv.except_osv(_('Warning!'), _('You have to create question and answer for survey.')) + else: + context.update({'active':False,'survey_id': ids[0]}) return { 'view_type': 'form', 'view_mode': 'form', From ce39ffe9271261cdc52b76e3bc981d177f7a6693 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Wed, 12 Sep 2012 16:52:45 +0530 Subject: [PATCH 191/726] [IMP]changed as per new spec update and make it work for crm changes done in crm bzr revid: sgo@tinyerp.com-20120912112245-3cp03024fiqb47qs --- addons/crm/crm_lead.py | 18 ++-- addons/crm/crm_lead_data.xml | 28 +++--- addons/mail/data/mail_data.xml | 10 --- addons/mail/mail_message.py | 45 +++------- addons/mail/mail_message_subtype.py | 8 +- addons/mail/mail_message_subtype.xml | 5 +- addons/mail/mail_thread.py | 41 ++++++--- addons/mail/static/src/js/mail_followers.js | 64 +++++-------- addons/mail/tests/test_mail.py | 99 ++++++--------------- 9 files changed, 106 insertions(+), 212 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index b7cc0f840d9..6b04be2244d 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -27,15 +27,13 @@ import time import tools from tools.translate import _ -from base.res.res_partner import format_address - CRM_LEAD_PENDING_STATES = ( crm.AVAILABLE_STATES[2][0], # Cancelled crm.AVAILABLE_STATES[3][0], # Done crm.AVAILABLE_STATES[4][0], # Pending ) -class crm_lead(base_stage, format_address, osv.osv): +class crm_lead(base_stage, osv.osv): """ CRM Lead Case """ _name = "crm.lead" _description = "Lead/Opportunity" @@ -107,12 +105,6 @@ class crm_lead(base_stage, format_address, osv.osv): return result, fold - def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): - res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu) - if view_type == 'form': - res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context) - return res - _group_by_full = { 'stage_id': _read_group_stage_ids } @@ -842,7 +834,7 @@ class crm_lead(base_stage, format_address, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change",context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), mail_subtype_new="crm_subtype_stage_change",context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -852,16 +844,16 @@ class crm_lead(base_stage, format_address, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=message, subtype="new", context=context) + self.message_post(cr, uid, [id], body=message, subtype_xml_id="crm_subtype_new", context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - return self.message_post(cr, uid, ids, body=message,subtype="lost", context=context) + return self.message_post(cr, uid, ids, body=message,subtype_xml_id="crm_subtype_lost", context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - return self.message_post(cr, uid, ids, body=message, subtype="won", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="crm_subtype_won", context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 9b3f5d7ec75..252e843cf30 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -155,32 +155,24 @@
                    - + new - + crm.lead - + won - + crm.lead - + lost - - - - stage change - + crm.lead - - - - - - - - + + stage change + crm.lead + diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index 80aff038dac..8e2af38f2ea 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -13,18 +13,8 @@ - - other - - - - - email - - comment - diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 686f3e3d381..9e228083b1b 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -20,13 +20,11 @@ ############################################################################## import logging -import openerp import tools from email.header import decode_header from operator import itemgetter from osv import osv, fields -from tools.translate import _ _logger = logging.getLogger(__name__) @@ -37,7 +35,6 @@ def decode(text): text = decode_header(text.replace('\r', '')) return ''.join([tools.ustr(x[0], x[1]) for x in text]) - class mail_message(osv.Model): """ Messages model: system notification (replacing res.log notifications), comments (OpenChatter discussion) and incoming emails. """ @@ -60,10 +57,7 @@ class mail_message(osv.Model): for message in self.browse(cr, uid, ids, context=context): if not message.model or not message.res_id: continue - try: - result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1]) - except openerp.exceptions.AccessDenied, e: - pass + result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1]) return result def _get_unread(self, cr, uid, ids, name, arg, context=None): @@ -154,7 +148,7 @@ class mail_message(osv.Model): def _message_dict_get(self, cr, uid, msg, context=None): """ Return a dict representation of the message browse record. """ - attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)] + attachment_ids = self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context) author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0] author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0] partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context) @@ -313,15 +307,15 @@ class mail_message(osv.Model): def unlink(self, cr, uid, ids, context=None): # cascade-delete attachments that are directly attached to the message (should only happen - # for mail.messages that act as parent for a standalone mail.mail record). + # for mail.messages that act as parent for a standalone mail.mail record. attachments_to_delete = [] - for message in self.browse(cr, uid, ids, context=context): - for attach in message.attachment_ids: - if attach.res_model == self._name and attach.res_id == message.id: + for mail in self.browse(cr, uid, ids, context=context): + for attach in mail.attachment_ids: + if attach.res_model == 'mail.message' and attach.res_id == mail.id: attachments_to_delete.append(attach.id) if attachments_to_delete: self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context) - return super(mail_message, self).unlink(cr, uid, ids, context=context) + return super(mail_message,self).unlink(cr, uid, ids, context=context) def notify(self, cr, uid, newid, context=None): """ Add the related record followers to the destination partner_ids. @@ -344,6 +338,9 @@ class mail_message(osv.Model): follow_ids = followers_obj.search(cr, uid, [('partner_id','=',p_id),('subtype_ids','in',[message.subtype_id.id]),('res_model','=',message.model),('res_id','=',message.res_id)], context=context) if follow_ids and len(follow_ids): missing_follow_ids.append(p_id) + subtype_record = self.pool.get('mail.message.subtype').browse(cr, uid, message.subtype_id.id,context=context) + if not subtype_record.res_model: + missing_follow_ids.append(p_id) message.write({'partner_ids': [(4, p_id) for p_id in missing_follow_ids]}) partners_to_notify |= extra_notified self.pool.get('mail.notification').notify(cr, uid, list(partners_to_notify), newid, context=context) @@ -354,25 +351,3 @@ class mail_message(osv.Model): default = {} default.update(message_id=False, headers=False) return super(mail_message, self).copy(cr, uid, id, default=default, context=context) - - #------------------------------------------------------ - # Tools - #------------------------------------------------------ - - def check_partners_email(self, cr, uid, partner_ids, context=None): - """ Verify that selected partner_ids have an email_address defined. - Otherwise throw a warning. """ - partner_wo_email_lst = [] - for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context): - if not partner.email: - partner_wo_email_lst.append(partner) - if not partner_wo_email_lst: - return {} - warning_msg = _('The following partners chosen as recipients for the email have no email address linked :') - for partner in partner_wo_email_lst: - warning_msg += '\n- %s' % (partner.name) - return {'warning': { - 'title': _('Partners email addresses not found'), - 'message': warning_msg, - } - } diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py index 2330e34e1d3..6eb349fc71e 100644 --- a/addons/mail/mail_message_subtype.py +++ b/addons/mail/mail_message_subtype.py @@ -29,15 +29,9 @@ class mail_message_subtype(osv.osv): _columns = { 'name': fields.char('Message Subtype ', size = 128, required = True, help = 'Message subtype, gives a more precise type on the message, especially for system notifications. For example, it can be a notification related to a new record (New), or to a stage change in a process (Stage change). Message subtypes allow to precisely tune the notifications the user want to receive on its wall.'), - 'model_ids': fields.many2many('ir.model', - 'mail_message_subtyp_message_rel', - 'message_subtype_id', 'model_id', 'Model', - help = "link some subtypes to several models, for projet/task"), + 'res_model': fields.char('Model',size = 128, help = "link subtype to model"), 'default': fields.boolean('Default', help = "When subscribing to the document, users will receive by default messages related to this subtype unless they uncheck this subtype"), } _defaults = { 'default': True, } - _sql_constraints = [ - ('name_uniq', 'unique (name)', 'The name of the message subtype must be unique !') - ] diff --git a/addons/mail/mail_message_subtype.xml b/addons/mail/mail_message_subtype.xml index 0bfdc2cad95..7d0eed2f4da 100644 --- a/addons/mail/mail_message_subtype.xml +++ b/addons/mail/mail_message_subtype.xml @@ -14,7 +14,7 @@ - + @@ -30,13 +30,12 @@ + - - diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 87c2e22d46b..23c038ce692 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -562,7 +562,7 @@ class mail_thread(osv.AbstractModel): self.message_post(cr, uid, [id], message, context=context) def message_post(self, cr, uid, thread_id, body='', subject=False, - type='notification', parent_id=False, attachments=None, subtype='comment', context=None, **kwargs): + type='notification', parent_id=False, attachments=None, subtype_xml_id='mail_subtype_comment', context=None, **kwargs): """ Post a new message in an existing thread, returning the new mail.message ID. Extra keyword arguments will be used as default column values for the new mail.message record. @@ -599,12 +599,13 @@ class mail_thread(osv.AbstractModel): values = kwargs subtype_obj = self.pool.get('mail.message.subtype') - if subtype: - subtypes = subtype_obj.name_search(cr, uid, subtype,context=context) - if len(subtypes): - subtype_browse = subtype_obj.browse(cr, uid, subtypes[0][0],context=context) - if self._name in [model.model for model in subtype_browse.model_ids]: - values['subtype_id']=subtype_browse.id + ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', subtype_xml_id) + if subtype_xml_id: + subtype_browse = subtype_obj.browse(cr, uid, ref[1],context=context) + if self._name == subtype_browse.res_model: + values['subtype_id']=subtype_browse.id + else: + values['subtype_id']=subtype_browse.id values.update({ 'model': context.get('thread_model', self._name) if thread_id else False, 'res_id': thread_id or False, @@ -628,14 +629,20 @@ class mail_thread(osv.AbstractModel): partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] return self.message_subscribe(cr, uid, ids, partner_ids, context=context) - def message_subscribe(self, cr, uid, ids, partner_ids, context=None): - """ Add partners to the records followers. """ + def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None): + """ Add partners to the records followers. + :param partner_ids: a list of partner_ids to subscribe + :param return: new value of followers if read_back key in context + """ + self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) if not subtype_ids: subtype_obj = self.pool.get('mail.message.subtype') - subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)],context=context) + subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('res_model', '=', self._name)],context=context) if subtype_ids: self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context) - return self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) + if context and context.get('read_back'): + return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] + return [] def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not @@ -645,8 +652,14 @@ class mail_thread(osv.AbstractModel): return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context) def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None): - """ Remove partners from the records followers. """ - return self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context) + """ Remove partners from the records followers. + :param partner_ids: a list of partner_ids to unsubscribe + :param return: new value of followers if read_back key in context + """ + self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context) + if context and context.get('read_back'): + return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] + return [] #------------------------------------------------------ # Thread state @@ -679,6 +692,6 @@ class mail_thread(osv.AbstractModel): def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids,context=None): followers_obj = self.pool.get('mail.followers') followers_ids = followers_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) #overright or add new one + return followers_obj.write(cr, uid, followers_ids, {'subtype_ids': [(6, 0 , subtype_ids)]}, context = context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 2126d60edf0..b1d62b76a62 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -33,12 +33,20 @@ openerp_mail_followers = function(session, mail) { }, start: function() { - // use actual_mode property on view to know if the view is in create mode anymore + var self = this; + // NB: all the widget should be modified to check the actual_mode property on view, not use + // any other method to know if the view is in create mode anymore this.view.on("change:actual_mode", this, this._check_visibility); this._check_visibility(); this.fetch_subtype(); + this.$el.find('ul.oe_mail_recthread_subtype').click(function () {self.update_subtype();}) + this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); self.fetch_subtype();}) + .mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) + .mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); + this.$el.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); }) + .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) + .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); this.reinit(); - this.bind_events(); }, _check_visibility: function() { @@ -46,40 +54,14 @@ openerp_mail_followers = function(session, mail) { if (this.view.get("actual_mode") !== "create"){this.fetch_subtype();} }, + destroy: function () { + this._super.apply(this, arguments); + }, + reinit: function() { this.$el.find('button.oe_mail_button_follow').hide(); this.$el.find('button.oe_mail_button_unfollow').hide(); - }, - - bind_events: function() { - var self = this; - this.$('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); }) - .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) - .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); - this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); self.fetch_subtype(); }); - this.$el.on('click','ul.oe_mail_recthread_subtype', function () {self.update_subtype();}) - this.$el.on('click', 'button.oe_mail_button_invite', function(event) { - action = { - type: 'ir.actions.act_window', - res_model: 'mail.wizard.invite', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: { - 'default_res_model': self.view.dataset.model, - 'default_res_id': self.view.datarecord.id - }, - } - self.do_action(action, function() { self.read_value(); }); - }); - }, - - read_value: function() { - var self = this; - return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) { - return results[0].message_follower_ids; - }).pipe(this.proxy('set_value')); + // this.$el.find('ul.oe_mail_recthread_subtype').hide() }, set_value: function(value_) { @@ -89,11 +71,11 @@ openerp_mail_followers = function(session, mail) { this.$el.find('div.oe_mail_recthread_aside').hide(); return; } - return this.fetch_followers(value_ || this.get_value()); + return this.fetch_followers(value_); }, fetch_followers: function (value_) { - return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers')); + return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers')); }, /** Display the followers, evaluate is_follower directly */ @@ -103,7 +85,7 @@ openerp_mail_followers = function(session, mail) { var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty(); this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')'); _(records).each(function (record) { - record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id); + record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.partner', 'image_small', record.id); $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list); }); if (this.message_is_follower) { @@ -149,22 +131,22 @@ openerp_mail_followers = function(session, mail) { }, do_follow: function () { - var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value')); + var context = new session.web.CompoundContext(this.build_context(), {'read_back': true}); + return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value')); }, //fetch subtype from subtype model fetch_subtype: function () { var self = this - var subtype_object = this.sub_model.call('search', [[['model_ids.model','=',this.view.model]]]); + var subtype_object = this.sub_model.call('search', [[['res_model','=',this.view.model]]]); subtype_object.then(function (subtype_ids){ self.sub_model.call('read', [subtype_ids || self.get_value(),['name', 'default']]).then(self.proxy('display_subtype')); }); }, do_unfollow: function () { - var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value')); + var context = new session.web.CompoundContext(this.build_context(), {'read_back': true}); + return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value')); }, }); }; diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 5da3456abe9..0ed1d2b38c0 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -19,8 +19,6 @@ # ############################################################################## -import tools - from openerp.tests import common from openerp.tools.html_sanitize import html_sanitize @@ -31,7 +29,7 @@ Received: by mail1.openerp.com (Postfix, from userid 10002) From: Sylvie Lelitre Subject: {subject} MIME-Version: 1.0 -Content-Type: multipart/alternative; +Content-Type: multipart/alternative; boundary="----=_Part_4200734_24778174.1344608186754" Date: Fri, 10 Aug 2012 14:16:26 +0000 Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com> @@ -54,9 +52,9 @@ Content-Transfer-Encoding: quoted-printable =20 =20 - +

                    Please call me as soon as possible this afternoon!

                    - +

                    --
                    Sylvie

                    @@ -84,42 +82,15 @@ Sylvie """ -class TestMailMockups(common.TransactionCase): +class test_mail(common.TransactionCase): def _mock_smtp_gateway(self, *args, **kwargs): return True - def _init_mock_build_email(self): - self._build_email_args_list = [] - self._build_email_kwargs_list = [] - def _mock_build_email(self, *args, **kwargs): - self._build_email_args_list.append(args) - self._build_email_kwargs_list.append(kwargs) - return self._build_email(*args, **kwargs) - - def setUp(self): - super(TestMailMockups, self).setUp() - # Install mock SMTP gateway - self._init_mock_build_email() - self._build_email = self.registry('ir.mail_server').build_email - self.registry('ir.mail_server').build_email = self._mock_build_email - self._send_email = self.registry('ir.mail_server').send_email - self.registry('ir.mail_server').send_email = self._mock_smtp_gateway - - def tearDown(self): - # Remove mocks - self.registry('ir.mail_server').build_email = self._build_email - self.registry('ir.mail_server').send_email = self._send_email - super(TestMailMockups, self).tearDown() - - -class test_mail(TestMailMockups): - - def _mock_send_get_mail_body(self, *args, **kwargs): - # def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None) - body = tools.append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner') - return body + self._build_email_args = args + self._build_email_kwargs = kwargs + return self.build_email_real(*args, **kwargs) def setUp(self): super(test_mail, self).setUp() @@ -135,9 +106,10 @@ class test_mail(TestMailMockups): self.res_users = self.registry('res.users') self.res_partner = self.registry('res.partner') - # Mock send_get_mail_body to test its functionality without other addons override - self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body - self.registry('mail.mail').send_get_mail_body = self._mock_send_get_mail_body + # Install mock SMTP gateway + self.build_email_real = self.registry('ir.mail_server').build_email + self.registry('ir.mail_server').build_email = self._mock_build_email + self.registry('ir.mail_server').send_email = self._mock_smtp_gateway # groups@.. will cause the creation of new mail groups self.mail_group_model_id = self.ir_model.search(self.cr, self.uid, [('model', '=', 'mail.group')])[0] @@ -147,11 +119,6 @@ class test_mail(TestMailMockups): self.group_pigs_id = self.mail_group.create(self.cr, self.uid, {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'}) - def tearDown(self): - # Remove mocks - self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body - super(test_mail, self).tearDown() - def test_00_message_process(self): cr, uid = self.cr, self.uid # Incoming mail creates a new mail_group "frogs" @@ -187,7 +154,7 @@ class test_mail(TestMailMockups): test_msg_id = '' mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id) self.mail_thread.message_process(cr, uid, None, mail_text) - new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0]) + new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id','=',test_msg_id)])[0]) self.assertEqual(new_mail.body, '\n

                    \nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
                    \n', 'plaintext mail incorrectly parsed') @@ -308,20 +275,18 @@ class test_mail(TestMailMockups): _attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')] # CASE1: post comment, body and subject specified - self._init_mock_build_email() msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment') message = self.mail_message.browse(cr, uid, msg_id) - sent_emails = self._build_email_kwargs_list + sent_email = self._build_email_kwargs # Test: notifications have been deleted self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id)]), 'mail.mail notifications should have been auto-deleted!') # Test: mail_message: subject is _subject, body is _body1 (no formatting done) self.assertEqual(message.subject, _subject, 'mail.message subject incorrect') self.assertEqual(message.body, _body1, 'mail.message body incorrect') - # Test: sent_email: email send by server: correct subject, body, body_alternative - for sent_email in sent_emails: - self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect') - self.assertEqual(sent_email['body'], _mail_body1 + '\n
                    Bert Tartopoils
                    \n', 'sent_email body incorrect') - self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils', 'sent_email body_alternative is incorrect') + # Test: sent_email: email send by server: correct subject, body; body_alternative + self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect') + self.assertEqual(sent_email['body'], _mail_body1, 'sent_email body incorrect') + self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1, '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_pids = set([p_a_id, p_b_id, p_c_id]) @@ -331,16 +296,14 @@ class test_mail(TestMailMockups): 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') # Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer) - for sent_email in sent_emails: - self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect') + self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect') # CASE2: post an email with attachments, parent_id, partner_ids # TESTS: automatic subject, signature in body_html, attachments propagation - self._init_mock_build_email() msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email', partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments) message = self.mail_message.browse(cr, uid, msg_id2) - sent_emails = self._build_email_kwargs_list + sent_email = self._build_email_kwargs self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!') # Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id @@ -348,11 +311,9 @@ class test_mail(TestMailMockups): self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect') self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect') # Test: sent_email: email send by server: correct subject, body, body_alternative - self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect') - for sent_email in sent_emails: - self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect') - self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect') - self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect') + self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect') + self.assertEqual(sent_email['body'], _mail_body2, 'sent_email body incorrect') + self.assertEqual(sent_email['body_alternative'], _mail_bodyalt2, 'sent_email body_alternative incorrect') # Test: mail_message: partner_ids = group followers message_pids = set([partner.id for partner in message.partner_ids]) test_pids = set([p_a_id, p_b_id, p_c_id, p_d_id]) @@ -362,8 +323,7 @@ class test_mail(TestMailMockups): 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') # Test: sent_email: email_to should contain b@b, c@c, not a@a (writer) - for sent_email in sent_emails: - self.assertTrue(set(sent_email['email_to']).issubset(set(['b@b', 'c@c'])), 'sent_email email_to incorrect') + self.assertEqual(set(sent_email['email_to']), set(['b@b', 'c@c']), 'sent_email email_to incorrect') # Test: attachments for attach in message.attachment_ids: self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect') @@ -450,14 +410,12 @@ class test_mail(TestMailMockups): self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message incorrect content_subtype') # 2. Post the comment, get created message - parent_id = message.id mail_compose.send_mail(cr, uid, [compose_id]) group_pigs.refresh() message = group_pigs.message_ids[0] - # Test: mail.message: subject as Re:.., body in html, parent_id + # Test: mail.message: subject as Re:.., body in html self.assertEqual(message.subject, _msg_reply, 'mail.message incorrect subject') self.assertIn('Administrator wrote:
                    Pigs rules
                    ', message.body, 'mail.message body is incorrect') - self.assertEqual(message.parent_id and message.parent_id.id, parent_id, 'mail.message parent_id incorrect') # Test: mail.message: attachments for attach in message.attachment_ids: self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect') @@ -501,7 +459,6 @@ class test_mail(TestMailMockups): # It will be updated as soon as we have fixed specs ! cr, uid = self.cr, self.uid group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) - def _compare_structures(struct1, struct2, n=0): # print '%scompare structure' % ('\t' * n) self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect') @@ -673,10 +630,10 @@ class test_mail(TestMailMockups): _mail_bodyalt2 = 'Pigs rules\nAdmin\n' filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)]) # Post comment with body and subject, comment preference - msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype='email') + msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mail_subtype_comment') notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)]) self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall") # New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message - msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other') - notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)]) - self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall") +# msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other') +# notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)]) +# self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall") From 6f0b8abe3159831e67434c5938bc867a98b462dd Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 11:05:40 +0530 Subject: [PATCH 192/726] [IMP]account,project,project_issue: changed as per new spec bzr revid: sgo@tinyerp.com-20120913053540-atfsrw8bkf16qo3t --- addons/account/account_invoice.py | 33 ++++++------- addons/account/data/account_data.xml | 26 +++++----- addons/account_voucher/account_voucher.py | 8 ++-- .../account_voucher/account_voucher_data.xml | 21 +++------ addons/analytic/analytic.py | 18 ++++++- addons/base_status/base_stage.py | 14 +++++- addons/project/project.py | 21 ++++----- addons/project/project_data.xml | 47 ++++++++++--------- addons/project_issue/project_issue.py | 4 +- addons/project_issue/project_issue_data.xml | 25 ++++------ 10 files changed, 109 insertions(+), 108 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 9dcbd877c67..8a7251b3856 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -395,23 +395,18 @@ class account_invoice(osv.osv): template_id = template and template[1] or False res = mod_obj.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form') res_id = res and res[1] or False - ctx = dict(context) - ctx.update({ - 'default_model': 'account.invoice', - 'default_res_id': ids[0], - 'default_use_template': True, - 'default_template_id': template_id, - }) + ctx = dict(context, active_model='account.invoice', active_id=ids[0]) + ctx.update({'mail.compose.template_id': template_id}) return { - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'mail.compose.message', - 'views': [(res_id, 'form')], - 'view_id': res_id, - 'type': 'ir.actions.act_window', - 'target': 'new', - 'context': ctx, - 'nodestroy': True, + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(res_id, 'form')], + 'view_id': res_id, + 'type': 'ir.actions.act_window', + 'target': 'new', + 'context': ctx, + 'nodestroy': True, } def confirm_paid(self, cr, uid, ids, context=None): @@ -1306,15 +1301,15 @@ class account_invoice(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id],body=_("%s created.") % (self._get_document_type(obj.type)), subtype="new", context=context) + self.message_post(cr, uid, [obj.id],body=_("%s created.") % (self._get_document_type(obj.type)), subtype_xml_id="analytic_subtype_new", context=context) def confirm_paid_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s paid.") % (self._get_document_type(obj.type)), subtype="paid", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s paid.") % (self._get_document_type(obj.type)), subtype_xml_id="invoice_subtype_paid", context=context) def invoice_cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype="cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s cancelled.") % (self._get_document_type(obj.type)), subtype_xml_id="invoice_subtype_cancelled", context=context) account_invoice() class account_invoice_line(osv.osv): diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml index bf3b3152552..22849a9b886 100644 --- a/addons/account/data/account_data.xml +++ b/addons/account/data/account_data.xml @@ -560,28 +560,24 @@ Invoice account.invoice
                    - + new - + account.analytic.account - + + new + account.invoice + + + paid - + account.invoice - + cancelled - + account.invoice - - - - - - - - - diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index ae670b3d0b7..d2976882981 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -1045,8 +1045,6 @@ class account_voucher(osv.osv): # if the amount encoded in voucher is equal to the amount unreconciled, we need to compute the # currency rate difference if line.amount == line.amount_unreconciled: - if not line.move_line_id.amount_residual: - raise osv.except_osv(_('Wrong bank statement line'),_("You have to delete the bank statement line which the payment was reconciled to manually. Please check the payment of the partner %s by the amount of %s.")%(line.voucher_id.partner_id.name, line.voucher_id.amount)) currency_rate_difference = line.move_line_id.amount_residual - amount else: currency_rate_difference = 0.0 @@ -1295,17 +1293,17 @@ class account_voucher(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): message = "%s created." % self._document_type[obj.type or False] - self.message_post(cr, uid, [obj.id], body=message, subtype="new", context=context) + self.message_post(cr, uid, [obj.id], body=message, subtype_xml_id="voucher_subtype_new", context=context) def post_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): message = "%s '%s' is posted." % (self._document_type[obj.type or False], obj.move_id.name) - self.message_post(cr, uid, [obj.id], body=message, subtype="post", context=context) + self.message_post(cr, uid, [obj.id], body=message, subtype_xml_id="voucher_subtype_post", context=context) def reconcile_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): message = "%s reconciled." % self._document_type[obj.type or False] - self.message_post(cr, uid, [obj.id], body=message, subtype="reconcile", context=context) + self.message_post(cr, uid, [obj.id], body=message, subtype_xml_id="voucher_subtype_reconcile", context=context) account_voucher() diff --git a/addons/account_voucher/account_voucher_data.xml b/addons/account_voucher/account_voucher_data.xml index a99a8735842..dd46a83777e 100644 --- a/addons/account_voucher/account_voucher_data.xml +++ b/addons/account_voucher/account_voucher_data.xml @@ -13,27 +13,18 @@ If you want to use advanced accounting features, you should install the "Account Module eInvoicing & Payments has been installed.
                    - - + + account.voucher - + post - + account.voucher - + reconcile - + account.voucher - - - - - - - - - diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py index a44fcb01653..776df713b4e 100644 --- a/addons/analytic/analytic.py +++ b/addons/analytic/analytic.py @@ -96,6 +96,22 @@ class account_analytic_account(osv.osv): res[row['id']][field] = row[field] return self._compute_level_tree(cr, uid, ids, child_ids, res, fields, context) + def name_get(self, cr, uid, ids, context=None): + if isinstance(ids, (int, long)): + ids=[ids] + if not ids: + return [] + res = [] + for account in self.browse(cr, uid, ids, context=context): + data = [] + acc = account + while acc: + data.insert(0, acc.name) + acc = acc.parent_id + data = ' / '.join(data) + res.append((account.id, data)) + return res + def _complete_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict): res = self.name_get(cr, uid, ids) return dict(res) @@ -281,7 +297,7 @@ class account_analytic_account(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Contract for %s has been created.") % (obj.partner_id.name), subtype="new", context=context) + self.message_post(cr, uid, [obj.id], body=_("Contract for %s has been created.") % (obj.partner_id.name), subtype_xml_id="analytic_subtype_new", context=context) account_analytic_account() diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 9bb2764d8bd..f72168cde46 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -362,17 +362,27 @@ class base_stage(object): msg = _('%s has been opened.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) self.message_post(cr, uid, [id], body=msg, context=context) return True + + def find_xml_id(self,cr,uid,ids,name,context=None): + subtype_obj = self.pool.get('mail.message.subtype') + irmodel_obj = self.pool.get('ir.model.data') + subtype_id = subtype_obj.search(cr,uid,[('res_model','=',self._name),('name','=',name)]) + ir_ids = irmodel_obj.search(cr,uid,[('model','=','mail.message.subtype'),('res_id','=',subtype_id)]) + ir_model_browse = irmodel_obj.browse(cr,uid,ir_ids) + return ir_model_browse.name def case_close_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=msg, subtype="closed", context=context) + xml_id = self.find_xml_id(cr, uid, ids, name="closed", context) + self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been cancelled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=msg, subtype="cancelled", context=context) + xml_id = self.find_xml_id(cr, uid, ids, name="cancelled", context) + self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True def case_pending_send_note(self, cr, uid, ids, context=None): diff --git a/addons/project/project.py b/addons/project/project.py index e1dea8e70c5..412e14fd8fd 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -41,9 +41,8 @@ class project_task_type(osv.osv): 'case_default': fields.boolean('Common to All Projects', help="If you check this field, this stage will be proposed by default on each new project. It will not assign this stage to existing projects."), 'project_ids': fields.many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', 'Projects'), - 'state': fields.selection(_TASK_STATE, 'Related Status', required=True, - help="The status of your document is automatically changed regarding the selected stage. " \ - "For example, if a stage is related to the status 'Close', when your document reaches this stage, it is automatically closed."), + 'state': fields.selection(_TASK_STATE, 'State', required=True, + help="The related state for the stage. The state of your document will automatically change regarding the selected stage. Example, a stage is related to the state 'Close', when your document reach this stage, it will be automatically closed."), 'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."), } @@ -514,23 +513,23 @@ def Project(): return project_id def create_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Project has been created."), subtype="new", context=context) + return self.message_post(cr, uid, ids, body=_("Project has been created."), subtype_xml_id="project_subtype_new", context=context) def set_open_send_note(self, cr, uid, ids, context=None): message = _("Project has been opened.") - return self.message_post(cr, uid, ids, body=message, subtype="open", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="project_subtype_open", context=context) def set_pending_send_note(self, cr, uid, ids, context=None): message = _("Project is now pending.") - return self.message_post(cr, uid, ids, body=message, subtype="pending", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="project_subtype_pending", context=context) def set_cancel_send_note(self, cr, uid, ids, context=None): message = _("Project has been cancelled.") - return self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="project_subtype_cancelled", context=context) def set_close_send_note(self, cr, uid, ids, context=None): message = _("Project has been closed.") - return self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="project_subtype_closed", context=context) def write(self, cr, uid, ids, vals, context=None): # if alias_model has been changed, update alias_model_id accordingly @@ -728,7 +727,7 @@ class task(base_stage, osv.osv): When the case is over, the state is set to \'Done\'.\ If the case needs to be reviewed then the state is \ set to \'Pending\'.'), - 'categ_ids': fields.many2many('project.category', string='Tags'), + 'categ_ids': fields.many2many('project.category', string='Categories'), 'kanban_state': fields.selection([('normal', 'Normal'),('blocked', 'Blocked'),('done', 'Ready To Pull')], 'Kanban State', help="A task's kanban state indicates special situations affecting it:\n" " * Normal is the default situation\n" @@ -1231,10 +1230,10 @@ class task(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change", context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id="task_subtype_stage_change", context=context) def create_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Task has been created."), subtype="new", context=context) + return self.message_post(cr, uid, ids, body=_("Task has been created."), subtype_xml_id="task_subtype_new", context=context) def case_draft_send_note(self, cr, uid, ids, context=None): msg = _('Task has been set as draft.') diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml index 34608d3abeb..0544b6d4e78 100644 --- a/addons/project/project_data.xml +++ b/addons/project/project_data.xml @@ -85,43 +85,48 @@ - + new - + project.project - + + new + project.task + + + open - + project.project - + pending - + project.project - + closed - + project.project - + + closed + project.task + + cancelled - + project.project - + + cancelled + project.task + + + stage change - + project.task - - - - - - - - - diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index d3f47ba9b3e..83eddb83d5e 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -503,7 +503,7 @@ class project_issue(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change", context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id="issue_subtype_stage_change", context=context) def case_get_note_msg_prefix(self, cr, uid, id, context=None): """ Override of default prefix for notifications. """ @@ -515,7 +515,7 @@ class project_issue(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Project issue created.") - return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="issue_subtype_new", context=context) def case_escalate_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): diff --git a/addons/project_issue/project_issue_data.xml b/addons/project_issue/project_issue_data.xml index 6ee704c6b39..f6c225a4d00 100644 --- a/addons/project_issue/project_issue_data.xml +++ b/addons/project_issue/project_issue_data.xml @@ -32,33 +32,24 @@ - + new - + project.issue - + stage change - + project.issue - + cancelled - + project.issue - + closed - - - - - - - - - - + project.issue From 8ca3f76711df87f17e2514dec84f63b82fee2ab7 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 11:59:28 +0530 Subject: [PATCH 193/726] [IMP]code improvement and other minor changes bzr revid: sgo@tinyerp.com-20120913062928-hvqnp116y49yrl4d --- addons/account/data/account_data.xml | 6 +----- addons/analytic/__openerp__.py | 3 ++- addons/analytic/analytic_data.xml | 10 ++++++++++ addons/base_status/base_stage.py | 11 +++++++---- addons/crm/crm_lead_data.xml | 5 +++++ 5 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 addons/analytic/analytic_data.xml diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml index 22849a9b886..7689ca2c253 100644 --- a/addons/account/data/account_data.xml +++ b/addons/account/data/account_data.xml @@ -560,11 +560,7 @@ Invoice account.invoice - - new - account.analytic.account - - + new account.invoice diff --git a/addons/analytic/__openerp__.py b/addons/analytic/__openerp__.py index 10762a1d2be..d90b2fd62ac 100644 --- a/addons/analytic/__openerp__.py +++ b/addons/analytic/__openerp__.py @@ -38,7 +38,8 @@ that have no counterpart in the general financial accounts. 'security/analytic_security.xml', 'security/ir.model.access.csv', 'analytic_sequence.xml', - 'analytic_view.xml' + 'analytic_view.xml', + 'analytic_data.xml' ], 'demo': [], 'installable': True, diff --git a/addons/analytic/analytic_data.xml b/addons/analytic/analytic_data.xml new file mode 100644 index 00000000000..cfd3b5e9b78 --- /dev/null +++ b/addons/analytic/analytic_data.xml @@ -0,0 +1,10 @@ + + + + + new + account.analytic.account + + + + \ No newline at end of file diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index f72168cde46..4b1cc3c6946 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -367,21 +367,24 @@ class base_stage(object): subtype_obj = self.pool.get('mail.message.subtype') irmodel_obj = self.pool.get('ir.model.data') subtype_id = subtype_obj.search(cr,uid,[('res_model','=',self._name),('name','=',name)]) - ir_ids = irmodel_obj.search(cr,uid,[('model','=','mail.message.subtype'),('res_id','=',subtype_id)]) + ir_ids = irmodel_obj.search(cr,uid,[('model','=','mail.message.subtype'),('res_id','in',subtype_id)]) + xml_id = False ir_model_browse = irmodel_obj.browse(cr,uid,ir_ids) - return ir_model_browse.name + if ir_model_browse: + xml_id = ir_model_browse[0].name + return xml_id def case_close_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - xml_id = self.find_xml_id(cr, uid, ids, name="closed", context) + xml_id = self.find_xml_id(cr, uid, ids, name="closed", context=context) self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been cancelled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - xml_id = self.find_xml_id(cr, uid, ids, name="cancelled", context) + xml_id = self.find_xml_id(cr, uid, ids, name="cancelled", context=context) self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 252e843cf30..633782ed233 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -174,5 +174,10 @@ crm.lead + + cancelled + crm.lead + + From 296ae6e24baa8918331d57c7c8e21b21a82cb4bc Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:11:01 +0530 Subject: [PATCH 194/726] [IMP]event:changed in event module as per new spec bzr revid: sgo@tinyerp.com-20120913064101-85pfg3kbbqnoufzx --- addons/event/event.py | 20 +++++++++---------- addons/event/event_data.xml | 39 ++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/addons/event/event.py b/addons/event/event.py index 8c755456d9c..82c0390ee03 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -287,27 +287,27 @@ class event_event(osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Event has been created.") - self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="event_subtype_new", context=context) return True def button_cancel_send_note(self, cr, uid, ids, context=None): message = _("Event has been cancelled.") - self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="event_subtype_cancelled", context=context) return True def button_draft_send_note(self, cr, uid, ids, context=None): message = _("Event has been set to draft.") - self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="event_subtype_new", context=context) return True def button_done_send_note(self, cr, uid, ids, context=None): message = _("Event has been done.") - self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="event_subtype_closed", context=context) return True def button_confirm_send_note(self, cr, uid, ids, context=None): message = _("Event has been confirmed.") - self.message_post(cr, uid, ids, body=message, subtype="confirmed", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="event_subtype_confirmed", context=context) return True event_event() @@ -353,7 +353,7 @@ class event_registration(osv.osv): return self.write(cr, uid, ids, {'state': 'draft'}, context=context) def confirm_registration(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_('State set to open'), context=context) + self.message_post(cr, uid, ids, body=_('State set to open'),subtype_xml_id="registration_subtype_confirmed", context=context) return self.write(cr, uid, ids, {'state': 'open'},context=context) def create(self, cr, uid, vals, context=None): @@ -383,13 +383,13 @@ class event_registration(osv.osv): if today >= registration.event_id.date_begin: values = {'state': 'done', 'date_closed': today} self.write(cr, uid, ids, values) - self.message_post(cr, uid, ids, body=_('State set to Done'), subtype="closed", context=context) + self.message_post(cr, uid, ids, body=_('State set to Done'), subtype_xml_id="registration_subtype_closed", context=context) else: raise osv.except_osv(_('Error!'),_("You must wait for the starting day of the event to do this action.") ) return True def button_reg_cancel(self, cr, uid, ids, context=None, *args): - self.message_post(cr, uid, ids, body=_('State set to Cancel'), subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=_('State set to Cancel'), subtype_xml_id="registration_subtype_cancelled", context=context) return self.write(cr, uid, ids, {'state': 'cancel'}) def mail_user(self, cr, uid, ids, context=None): @@ -459,12 +459,12 @@ class event_registration(osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Registration has been created.") - self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="registration_subtype_new", context=context) return True def do_draft_send_note(self, cr, uid, ids, context=None): message = _("Registration has been set as draft.") - self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="registration_subtype_new", context=context) return True event_registration() diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml index 608dcdb4e8f..814fd0b179c 100644 --- a/addons/event/event_data.xml +++ b/addons/event/event_data.xml @@ -12,34 +12,51 @@ automatic 100 - + + new + event.event - + closed + event.event - + cancelled + event.event - + confirmed + event.event - - - - - + + + + new + event.registration + - - + + closed + event.registration + + cancelled + event.event + + + + confirmed + event.registration + + From 66e8595b01b0c1d38190b1222d0955b710b6c1db Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:28:54 +0530 Subject: [PATCH 195/726] [IMP]changed in all hr module for subtype bzr revid: sgo@tinyerp.com-20120913065854-7y5jkls3q2jebduv --- addons/hr_holidays/hr_holidays.py | 6 ++-- addons/hr_holidays/hr_holidays_data.xml | 21 ++++---------- addons/hr_recruitment/hr_recruitment.py | 14 ++++----- addons/hr_recruitment/hr_recruitment_data.xml | 29 +++++++------------ .../hr_timesheet_invoice.py | 8 ++--- .../hr_timesheet_invoice_data.xml | 25 +++++----------- 6 files changed, 38 insertions(+), 65 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 4136abbb2f7..4e85313e2e4 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -364,7 +364,7 @@ class hr_holidays(osv.osv): def create_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): self.message_post(cr, uid, ids, - _("The request has been created and is waiting confirmation."),subtype="new", context=context) + _("The request has been created and is waiting confirmation."),subtype_xml_id="hr_holidays_subtype_new", context=context) return True def holidays_confirm_notificate(self, cr, uid, ids, context=None): @@ -384,12 +384,12 @@ class hr_holidays(osv.osv): _("The request has been double validated. The validation process is now over."), context=context) else: self.message_post(cr, uid, [obj.id], - _("The request has been approved. The validation process is now over."), subtype="approved", context=context) + _("The request has been approved. The validation process is now over."), subtype_xml_id="hr_holidays_subtype_approved", context=context) def holidays_refuse_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_post(cr, uid, [obj.id], - _("The request has been refused. The validation process is now over."), subtype="refused", context=context) + _("The request has been refused. The validation process is now over."), subtype_xml_id="hr_holidays_subtype_refused", context=context) class resource_calendar_leaves(osv.osv): diff --git a/addons/hr_holidays/hr_holidays_data.xml b/addons/hr_holidays/hr_holidays_data.xml index ad337b72c62..8ddfb79a527 100644 --- a/addons/hr_holidays/hr_holidays_data.xml +++ b/addons/hr_holidays/hr_holidays_data.xml @@ -50,28 +50,19 @@ Once validated, they are visible in the employee's calendar. HR officers can def brown - + new - + hr.holidays - + approved - + hr.holidays - + refused - + hr.holidays - - - - - - - - - diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 25be4f3c3f1..6d38c4e4e08 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -461,14 +461,14 @@ class hr_applicant(base_stage, osv.Model): """ Override of the (void) default notification method. """ if not stage_id: return True stage_name = self.pool.get('hr.recruitment.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change", context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id="hr_recruitment_subtype_stage_change", context=context) def case_get_note_msg_prefix(self, cr, uid, id, context=None): return 'Applicant' def case_open_send_note(self, cr, uid, ids, context=None): message = _("Applicant has been set in progress.") - return self.message_post(cr, uid, ids, body=message, subtype="in progress", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="hr_recruitment_subtype_in_progress", context=context) def case_close_send_note(self, cr, uid, ids, context=None): if context is None: @@ -476,23 +476,23 @@ class hr_applicant(base_stage, osv.Model): for applicant in self.browse(cr, uid, ids, context=context): if applicant.emp_id: message = _("Applicant has been hired and created as an employee.") - self.message_post(cr, uid, [applicant.id], body=message, subtype="hired", context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype_xml_id="hr_recruitment_subtype_hired", context=context) else: message = _("Applicant has been hired.") - self.message_post(cr, uid, [applicant.id], body=message, subtype="hired", context=context) + self.message_post(cr, uid, [applicant.id], body=message, subtype_xml_id="hr_recruitment_subtype_hired", context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): msg = 'Applicant refused.' - return self.message_post(cr, uid, ids, body=msg, subtype="refused", context=context) + return self.message_post(cr, uid, ids, body=msg, subtype_xml_id="hr_recruitment_subtype_refused", context=context) def case_reset_send_note(self, cr, uid, ids, context=None): message =_("Applicant has been set as new.") - return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="hr_recruitment_subtype_new", context=context) def create_send_note(self, cr, uid, ids, context=None): message = _("Applicant has been created.") - return self.message_post(cr, uid, ids, body=message, subtype="new", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="hr_recruitment_subtype_new", context=context) class hr_job(osv.osv): diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml index 30ff9118584..dedeb20a3dc 100644 --- a/addons/hr_recruitment/hr_recruitment_data.xml +++ b/addons/hr_recruitment/hr_recruitment_data.xml @@ -462,38 +462,29 @@ You can automatically receive job application though an email gateway, see the H - + new - + hr.applicant - + hired - + hr.applicant - + refused - + hr.applicant - + stage change - + hr.applicant - + in progress - + hr.applicant - - - - - - - - - diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py index 4ed61119a5f..e3f54609e95 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py @@ -95,25 +95,25 @@ class account_analytic_account(osv.osv): def set_close(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'close'}, context=context) message = _("Contract has been closed.") - self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="analytic_account_subtype_closed", context=context) return True def set_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'cancelled'}, context=context) message = _("Contract has been cancelled.") - self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="analytic_account_invoice_subtype_cancelled", context=context) return True def set_open(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'open'}, context=context) message = _("Contract has been opened.") - self.message_post(cr, uid, ids, body=message, subtype="open", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="analytic_account_subtype_open", context=context) return True def set_pending(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'pending'}, context=context) message = _("Contract has been set as pending.") - self.message_post(cr, uid, ids, body=message, subtype="pending", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="analytic_account_subtype_pending", context=context) return True account_analytic_account() diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml b/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml index 5cc5024d591..29a3233f509 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice_data.xml @@ -17,32 +17,23 @@ 50.0 - + closed - + account.analytic.account - + pending - + account.analytic.account - + open - + account.analytic.account - + cancelled - + account.analytic.account - - - - - - - - - From 97026e96d30c103a6873f66da0e50b4f47ece37f Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:33:33 +0530 Subject: [PATCH 196/726] [IMP]changed in idea for subtype bzr revid: sgo@tinyerp.com-20120913070333-8mvke4g0h13r6e6d --- addons/idea/idea.py | 8 ++++---- addons/idea/idea_data.xml | 25 ++++++++----------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/addons/idea/idea.py b/addons/idea/idea.py index e33c9b99014..f8346ec2bba 100644 --- a/addons/idea/idea.py +++ b/addons/idea/idea.py @@ -67,21 +67,21 @@ class idea_idea(osv.osv): def idea_cancel(self, cr, uid, ids, context={}): self.write(cr, uid, ids, { 'state': 'cancel' }) - self.message_post(cr, uid, ids, body=_('Idea cancelled.'), subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=_('Idea cancelled.'), subtype_xml_id="idea_subtype_cancelled", context=context) return True def idea_open(self, cr, uid, ids, context={}): self.write(cr, uid, ids, { 'state': 'open'}) - self.message_post(cr, uid, ids, body=_('Idea accepted.'), subtype="open", context=context) + self.message_post(cr, uid, ids, body=_('Idea accepted.'), subtype_xml_id="idea_subtype_open", context=context) return True def idea_close(self, cr, uid, ids, context={}): - self.message_post(cr, uid, ids, body=_('Idea closed.'), subtype="closed", context=context) + self.message_post(cr, uid, ids, body=_('Idea closed.'), subtype_xml_id="idea_subtype_closed", context=context) self.write(cr, uid, ids, { 'state': 'close' }) return True def idea_draft(self, cr, uid, ids, context={}): - self.message_post(cr, uid, ids, body=_('Idea reset to draft.'), subtype="new", context=context) + self.message_post(cr, uid, ids, body=_('Idea reset to draft.'), subtype_xml_id="idea_subtype_new", context=context) self.write(cr, uid, ids, { 'state': 'draft' }) return True idea_idea() diff --git a/addons/idea/idea_data.xml b/addons/idea/idea_data.xml index 36ccf2e992e..b4f3f70d2dd 100644 --- a/addons/idea/idea_data.xml +++ b/addons/idea/idea_data.xml @@ -17,32 +17,23 @@ - + new - + idea.idea - + open - + idea.idea - + cancelled - + idea.idea - + closed - - - - - - - - - - + idea.idea From fa5f1e174e8e0c525edc6e5a43a3d0681a11d77c Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:44:30 +0530 Subject: [PATCH 197/726] [IMP]changed in mrp and mrp_operations for subtype bzr revid: sgo@tinyerp.com-20120913071430-o7bml82s6tgnwn4h --- addons/mrp/mrp.py | 10 +++---- addons/mrp/mrp_data.xml | 29 +++++++------------- addons/mrp_operations/mrp_operation_data.xml | 29 +++++++------------- addons/mrp_operations/mrp_operations.py | 10 +++---- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 40d8d1b7e5f..bc0baae71e8 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -1044,27 +1044,27 @@ class mrp_production(osv.osv): # --------------------------------------------------- def create_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Manufacturing order has been created."), subtype="new", context=context) + self.message_post(cr, uid, ids, body=_("Manufacturing order has been created."), subtype_xml_id="mrp_subtype_new", context=context) return True def action_cancel_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order has been canceled.") - self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_subtype_cancelled", context=context) return True def action_ready_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order is ready to produce.") - self.message_post(cr, uid, ids, body=message, subtype="ready", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_subtype_ready", context=context) return True def action_in_production_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order is in production.") - self.message_post(cr, uid, ids, body=message, subtype="production", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_subtype_production", context=context) return True def action_done_send_note(self, cr, uid, ids, context=None): message = _("Manufacturing order has been done.") - self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_subtype_closed", context=context) return True def action_confirm_send_note(self, cr, uid, ids, context=None): diff --git a/addons/mrp/mrp_data.xml b/addons/mrp/mrp_data.xml index 6ee7cc82dd2..3740f03bdc8 100644 --- a/addons/mrp/mrp_data.xml +++ b/addons/mrp/mrp_data.xml @@ -27,38 +27,29 @@ From the Manufacturing Settings, you can choose to compute production schedules 1 - + new - + mrp.production - + ready - + mrp.production - + production - + mrp.production - + cancelled - + mrp.production - + closed - + mrp.production - - - - - - - - - diff --git a/addons/mrp_operations/mrp_operation_data.xml b/addons/mrp_operations/mrp_operation_data.xml index e2d7f9f0a56..812ce3da536 100644 --- a/addons/mrp_operations/mrp_operation_data.xml +++ b/addons/mrp_operations/mrp_operation_data.xml @@ -31,38 +31,29 @@ - + new - + mrp.production.workcenter.line - + started - + mrp.production.workcenter.line - + pending - + mrp.production.workcenter.line - + cancelled - + mrp.production.workcenter.line - + closed - + mrp.production.workcenter.line - - - - - - - - - diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index a18eb4141ba..6ed636850f1 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -224,7 +224,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been created for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype="new", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="new", context=context) return True def action_start_send_note(self, cr, uid, ids, context=None): @@ -232,7 +232,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been started for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype="started", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="started", context=context) return True def action_done_send_note(self, cr, uid, ids, context=None): @@ -240,7 +240,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been done for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype="closed", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="closed", context=context) return True def action_pending_send_note(self, cr, uid, ids, context=None): @@ -248,7 +248,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order is pending for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype="pending", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="pending", context=context) return True def action_cancel_send_note(self, cr, uid, ids, context=None): @@ -256,7 +256,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been cancelled for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype="cancelled", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="cancelled", context=context) return True mrp_production_workcenter_line() From 2e7de7cf6fad0212d3d2a8953fba64d8b5aa77a2 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:50:05 +0530 Subject: [PATCH 198/726] [IMP]changed in mrp_repair for subtype bzr revid: sgo@tinyerp.com-20120913072005-cmlf91arfwpxnv6o --- addons/mrp_repair/mrp_repair.py | 14 +++++----- addons/mrp_repair/mrp_repair_data.xml | 37 ++++++++++----------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 44624044090..202f9efd391 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -571,40 +571,40 @@ class mrp_repair(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Repair Order for %s has been created." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, subtype="new", context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype_xml_id="mrp_repair_subtype_new", context=context) return True def set_start_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Repair Order for %s has been started." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, subtype="started", context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype_xml_id="mrp_repair_subtype_started", context=context) return True def set_toinvoiced_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _("Draft Invoice of %s %s waiting for validation.") % (repair.invoice_id.amount_total, repair.invoice_id.currency_id.symbol) - self.message_post(cr, uid, [repair.id], body=message, subtype="pending", context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype_xml_id="mrp_repair_subtype_pending", context=context) return True def set_confirm_send_note(self, cr, uid, ids, context=None): for repair in self.browse(cr, uid, ids, context): message = _( "Repair Order for %s has been accepted." % (repair.product_id.name)) - self.message_post(cr, uid, [repair.id], body=message, subtype="accepted", context=context) + self.message_post(cr, uid, [repair.id], body=message, subtype_xml_id="mrp_repair_subtype_accepted", context=context) return True def set_cancel_send_note(self, cr, uid, ids, context=None): message = _("Repair has been cancelled.") - self.message_post(cr, uid, ids, body=message, subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_repair_subtype_cancelled", context=context) return True def set_ready_send_note(self, cr, uid, ids, context=None): message = _("Repair Order is now ready to repair.") - self.message_post(cr, uid, ids, body=message, subtype="ready", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_repair_subtype_ready", context=context) return True def set_done_send_note(self, cr, uid, ids, context=None): message = _("Repair Order is closed.") - self.message_post(cr, uid, ids, body=message, subtype="closed", context=context) + self.message_post(cr, uid, ids, body=message, subtype_xml_id="mrp_repair_subtype_closed", context=context) return True mrp_repair() diff --git a/addons/mrp_repair/mrp_repair_data.xml b/addons/mrp_repair/mrp_repair_data.xml index b45b7ec3105..6414e07f713 100644 --- a/addons/mrp_repair/mrp_repair_data.xml +++ b/addons/mrp_repair/mrp_repair_data.xml @@ -1,47 +1,38 @@ - + new - + mrp.repair - + started - + mrp.repair - + ready - + mrp.repair - + pending - + mrp.repair - + accepted - + mrp.repair - + cancelled - + mrp.repair - + closed - + mrp.repair - - - - - - - - - From 2e3f2e2458d71cdf693c6ec97e3d9cc28d4a6e75 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 12:59:49 +0530 Subject: [PATCH 199/726] [IMP]changed in procurement for subtype bzr revid: sgo@tinyerp.com-20120913072949-pny1yj3ke2gj2rr3 --- addons/procurement/procurement.py | 12 ++++----- addons/procurement/procurement_data.xml | 35 ++++++++++--------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 1cb695663df..dcb47f1af88 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -496,22 +496,22 @@ class procurement_order(osv.osv): return obj_id def create_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been created."), subtype="new", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been created."), subtype_xml_id="procurement_subtype_new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been confirmed."), subtype="confirmed", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been confirmed."), subtype_xml_id="procurement_subtype_confirmed", context=context) def running_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been set to running."), subtype="running", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been set to running."), subtype_xml_id="procurement_subtype_running", context=context) def ready_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been set to ready."), subtype="ready", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been set to ready."), subtype_xml_id="procurement_subtype_ready", context=context) def cancel_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been cancelled."), subtype_xml_id="procurement_subtype_cancelled", context=context) def done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype="closed", context=context) + self.message_post(cr, uid, ids, body=_("Procurement has been done."), subtype_xml_id="procurement_subtype_closed", context=context) procurement_order() diff --git a/addons/procurement/procurement_data.xml b/addons/procurement/procurement_data.xml index 1f60977c4dd..950c487ae53 100644 --- a/addons/procurement/procurement_data.xml +++ b/addons/procurement/procurement_data.xml @@ -32,36 +32,29 @@ - - + + new + procurement.order - + confirmed - + procurement.order - + ready - + procurement.order - + running - + procurement.order - - + + cancelled + procurement.order - + closed - - - - - - - - - - + procurement.order \ No newline at end of file From ad6e9d96e4d6f0f33f48415e13ffebcaf7992b77 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:27:27 +0530 Subject: [PATCH 200/726] [IMP]changed in sale module for subtype update specification bzr revid: sgo@tinyerp.com-20120913085727-7swp0404g99fkf7l --- addons/stock/stock.py | 18 +++++++++++++----- addons/stock/stock_data.xml | 29 +++++++++++++---------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index d577e69e237..50e85fa5191 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1379,13 +1379,13 @@ class stock_picking(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(obj.type)), subtype="new", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(obj.type)), subtype_xml_id="stock_in_subtype_new", context=context) def scrap_send_note(self, cr, uid, ids, quantity, uom, name, context=None): - return self.message_post(cr, uid, ids, body= _("%s %s %s has been moved to scrap.") % (quantity, uom, name), subtype="moved", context=context) + return self.message_post(cr, uid, ids, body= _("%s %s %s has been moved to scrap.") % (quantity, uom, name),context=context) def back_order_send_note(self, cr, uid, ids, back_name, context=None): - return self.message_post(cr, uid, ids, body=_("Back order %s has been created.") % (back_name), subtype="new", context=context) + return self.message_post(cr, uid, ids, body=_("Back order %s has been created.") % (back_name), subtype_xml_id="stock_in_subtype_new", context=context) def ship_done_send_note(self, cr, uid, ids, context=None): type_dict = { @@ -1393,12 +1393,20 @@ class stock_picking(osv.osv): 'in': 'received', 'internal': 'moved', } + xml_id_dict = { + 'out':'stock_out_subtype_delivered', + 'in' : 'stock_in_subtype_received' + } for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype=type_dict.get(obj.type), context=context) + self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype_xml_id=xml_id_dict.get(obj.type), context=context) def ship_cancel_send_note(self, cr, uid, ids, context=None): + xml_id_dict = { + 'out':'stock_out_subtype_cancelled', + 'in' : 'stock_in_subtype_cancelled' + } for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), subtype="cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), subtype_xml_id=xml_id_dict.get(obj.type), context=context) stock_picking() diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index f83b0ada388..a59642fa912 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -170,30 +170,27 @@ watch your stock valuation, and track production lots upstream and downstream (b - - + + new + stock.picking.in - + delivered - + stock.picking.out - + received - + stock.picking.in - - + + cancelled + stock.picking.in - - - - - - - - + + cancelled + stock.picking.out From 986e5817d18b149c3d31cc8c123b878a3e6b62b9 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:32:12 +0530 Subject: [PATCH 201/726] [IMP]changed in sale module for subtype update specification bzr revid: sgo@tinyerp.com-20120913090212-8c9jgb38x1d6517j --- addons/sale/sale.py | 10 +++++----- addons/sale/sale_data.xml | 29 ++++++++++------------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 0af625ed7d9..0f01909ac7f 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1032,7 +1032,7 @@ class sale_order(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Quotation for %s has been created.") % (obj.partner_id.name), subtype="new", context=context) + self.message_post(cr, uid, [obj.id], body=_("Quotation for %s has been created.") % (obj.partner_id.name), subtype_xml_id="sale_subtype_new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): @@ -1040,7 +1040,7 @@ class sale_order(osv.osv): def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), subtype="cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), subtype_xml_id="sale_subtype_cancelled", context=context) def delivery_send_note(self, cr, uid, ids, picking_id, context=None): for order in self.browse(cr, uid, ids, context=context): @@ -1052,15 +1052,15 @@ class sale_order(osv.osv): self.message_post(cr, uid, [order.id], body=_("Delivery Order %s scheduled for %s.") % (picking.name, picking_date_str), context=context) def delivery_end_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Order delivered."), subtype="delivered", context=context) + self.message_post(cr, uid, ids, body=_("Order delivered."), subtype_xml_id="sale_subtype_delivered", context=context) def invoice_paid_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype="paid", context=context) + self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype_xml_id="sale_subtype_paid", context=context) def invoice_send_note(self, cr, uid, ids, invoice_id, context=None): for order in self.browse(cr, uid, ids, context=context): for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id): - self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype="pending", context=context) + self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype_xml_id="sale_subtype_pending", context=context) def action_cancel_draft_send_note(self, cr, uid, ids, context=None): return self.message_post(cr, uid, ids, body=_('Sale order set to draft.'), context=context) diff --git a/addons/sale/sale_data.xml b/addons/sale/sale_data.xml index 2f4b81b27f4..4eca7f60c8f 100644 --- a/addons/sale/sale_data.xml +++ b/addons/sale/sale_data.xml @@ -50,37 +50,28 @@ If you need to manage your sales pipeline (leads, opportunities, phonecalls), you can install the module <i>CRM</i> from the top menu Settings. - + new - + sale.order - + cancelled - + sale.order - + paid - + sale.order - + pending - + sale.order - + delivered - - - - - - - - - - + sale.order From c67edb99bb891c468fedb6b4a373fe9da1843ebc Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:38:34 +0530 Subject: [PATCH 202/726] [IMP]changed in purchase module for subtype update specification bzr revid: sgo@tinyerp.com-20120913090834-5lf57kikymrzsg8z --- addons/purchase/purchase.py | 12 ++++++------ addons/purchase/purchase_data.xml | 29 ++++++++++------------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index c950c852261..b0f10d3f71f 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -740,7 +740,7 @@ class purchase_order(osv.osv): return [('state', '=', 'draft')] def create_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Request for quotation created."), subtype="new", context=context) + return self.message_post(cr, uid, ids, body=_("Request for quotation created."), subtype_xml_id="purchase_subtype_new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): @@ -758,20 +758,20 @@ class purchase_order(osv.osv): def invoice_send_note(self, cr, uid, ids, invoice_id, context=None): for order in self.browse(cr, uid, ids, context=context): for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id): - self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s is waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype="pending", context=context) + self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s is waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype_xml_id="purchase_subtype_pending", context=context) def shipment_done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("""Shipment received."""), subtype="received", context=context) + self.message_post(cr, uid, ids, body=_("""Shipment received."""), subtype_xml_id="purchase_subtype_received", context=context) def invoice_done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype="paid", context=context) + self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype_xml_id="purchase_subtype_paid", context=context) def draft_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Purchase Order has been set to draft."), context=context) + return self.message_post(cr, uid, ids, body=_("Purchase Order has been set to draft."), subtype_xml_id="purchase_subtype_new", context=context) def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), subtype="cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), subtype_xml_id="purchase_subtype_cancelled", context=context) purchase_order() diff --git a/addons/purchase/purchase_data.xml b/addons/purchase/purchase_data.xml index a84564b2360..aa62e84e19d 100644 --- a/addons/purchase/purchase_data.xml +++ b/addons/purchase/purchase_data.xml @@ -49,37 +49,28 @@ You can also manage purchase requisitions, see also the Purchase Settings. - + new - + purchase.order - + paid - + purchase.order - + pending - + purchase.order - + received - + purchase.order - + cancelled - + purchase.order - - - - - - - - - From 9524b34e314511191fc2c2265a44e5c9594f645c Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:42:08 +0530 Subject: [PATCH 203/726] [IMP]changed in purchase_requisition module for subtype update specification bzr revid: sgo@tinyerp.com-20120913091208-si6e042trpzdyq6m --- .../purchase_requisition.py | 8 +++---- .../purchase_requisition_data.xml | 23 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index a3df366381d..5d8d2bb2f87 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -94,13 +94,13 @@ class purchase_requisition(osv.osv): self.message_post(cr, uid, ids, body=_("Draft Requisition has been sent to suppliers."), context=context) def reset_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Purchase Requisition has been set to draft."), subtype="new", context=context) + self.message_post(cr, uid, ids, body=_("Purchase Requisition has been set to draft."), subtype_xml_id="requisition_subtype_new", context=context) def done_to_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Purchase Requisition has been done."), subtype="closed", context=context) + self.message_post(cr, uid, ids, body=_("Purchase Requisition has been done."), subtype_xml_id="requisition_subtype_closed", context=context) def cancel_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Purchase Requisition has been cancelled."), subtype="cancelled", context=context) + self.message_post(cr, uid, ids, body=_("Purchase Requisition has been cancelled."), subtype_xml_id="requisition_subtype_cancelled", context=context) def _planned_date(self, requisition, delay=0.0): company = requisition.company_id @@ -184,7 +184,7 @@ class purchase_requisition(osv.osv): return res def create_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Purchase Requisition has been created."), subtype="new", context=context) + return self.message_post(cr, uid, ids, body=_("Purchase Requisition has been created."), subtype_xml_id="requisition_subtype_new", context=context) def create(self, cr, uid, vals, context=None): requisition = super(purchase_requisition, self).create(cr, uid, vals, context=context) diff --git a/addons/purchase_requisition/purchase_requisition_data.xml b/addons/purchase_requisition/purchase_requisition_data.xml index 2b22c2057a1..534bf2fe2a7 100644 --- a/addons/purchase_requisition/purchase_requisition_data.xml +++ b/addons/purchase_requisition/purchase_requisition_data.xml @@ -7,24 +7,17 @@ model="ir.values" name="set"/> - + closed - + purchase.requisition - - + + new + purchase.requisition - - - - - - - - - - - + + cancelled + purchase.requisition \ No newline at end of file From 18ceddcf2ee7086fe2e2d512e415064986febf9c Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:45:02 +0530 Subject: [PATCH 204/726] [IMP]minor changes bzr revid: sgo@tinyerp.com-20120913091502-dvlpgoa3dr72km04 --- addons/event/event_data.xml | 4 ---- addons/mail/tests/test_mail.py | 4 ---- 2 files changed, 8 deletions(-) diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml index 814fd0b179c..bc7f71ef664 100644 --- a/addons/event/event_data.xml +++ b/addons/event/event_data.xml @@ -16,24 +16,20 @@ new event.event - closed event.event - cancelled event.event - confirmed event.event - diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index e3718d23855..9b0586d5d5c 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -636,7 +636,3 @@ class test_mail(common.TransactionCase): msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mail_subtype_comment') notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)]) self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall") - # New post: test automatic subject, signature in html, add a partner, email preference, parent_id previous message -# msg_id2 = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body2,subject=_subject, type='email', subtype='other') -# notif_ids2 = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id2)]) -# self.assertTrue(len(notif_ids2) == 0,"subtype is false cannot show notification on wall") From e6eafcaf22aa4c84ca751f1e6cd2f06a0833c987 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 14:47:57 +0530 Subject: [PATCH 205/726] [IMP]minor changes in account bzr revid: sgo@tinyerp.com-20120913091757-6izlnq34z3v9jd7n --- addons/account_voucher/account_voucher_data.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/account_voucher/account_voucher_data.xml b/addons/account_voucher/account_voucher_data.xml index dd46a83777e..a59993aae6b 100644 --- a/addons/account_voucher/account_voucher_data.xml +++ b/addons/account_voucher/account_voucher_data.xml @@ -14,6 +14,7 @@ If you want to use advanced accounting features, you should install the "Account + new account.voucher From 53a67e065236f549cd07b35406cc59181417ee55 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 15:12:09 +0530 Subject: [PATCH 206/726] [IMP]change in mrp bzr revid: sgo@tinyerp.com-20120913094209-4r0laz8gtmcz1tsq --- addons/mrp_operations/mrp_operations.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index 6ed636850f1..53eaceed066 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -224,7 +224,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been created for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="new", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="mrp_operations_subtype_new", context=context) return True def action_start_send_note(self, cr, uid, ids, context=None): @@ -232,7 +232,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been started for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="started", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="mrp_operations_subtype_started", context=context) return True def action_done_send_note(self, cr, uid, ids, context=None): @@ -240,7 +240,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been done for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="closed", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="mrp_operations_subtype_closed", context=context) return True def action_pending_send_note(self, cr, uid, ids, context=None): @@ -248,7 +248,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order is pending for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="pending", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="mrp_operations_subtype_pending", context=context) return True def action_cancel_send_note(self, cr, uid, ids, context=None): @@ -256,7 +256,7 @@ class mrp_production_workcenter_line(osv.osv): for workorder in self.browse(cr, uid, ids): for prod in prod_obj.browse(cr, uid, [workorder.production_id]): message = _("Work order has been cancelled for production order %s.") % (prod.id.name) - self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="cancelled", context=context) + self.message_post(cr, uid, [workorder.id], body=message, subtype_xml_id="mrp_operations_subtype_cancelled", context=context) return True mrp_production_workcenter_line() From 458899673b2d06572ea68b1874b56767d7966a76 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 15:33:07 +0530 Subject: [PATCH 207/726] [IMP]change in mrp operations openerp.py bzr revid: sgo@tinyerp.com-20120913100307-4f49x1my6ajzzfiz --- addons/mrp_operations/__openerp__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mrp_operations/__openerp__.py b/addons/mrp_operations/__openerp__.py index a5bda80f924..ba2e2d88637 100644 --- a/addons/mrp_operations/__openerp__.py +++ b/addons/mrp_operations/__openerp__.py @@ -58,6 +58,7 @@ So, that we can compare the theoretic delay and real delay. 'depends': ['mrp'], 'data': [ 'security/ir.model.access.csv', + 'mrp_operation_data.xml', 'mrp_operations_workflow.xml', 'mrp_operations_view.xml', 'mrp_operations_report.xml', @@ -65,7 +66,7 @@ So, that we can compare the theoretic delay and real delay. 'process/mrp_operation_process.xml', 'mrp_operations_workflow_instance.xml' ], - 'demo': ['mrp_operation_data.xml', + 'demo': [ 'mrp_operations_demo.yml' ], 'test': [ From 17987c7e2c71a695a5d3fcff324c29067ba6b7ab Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 15:54:56 +0530 Subject: [PATCH 208/726] [IMP]crm yml improve for subtype bzr revid: sgo@tinyerp.com-20120913102456-c74asnmmh6kx5270 --- addons/crm/test/process/crm_message_subtype.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index 3dd042c1279..46c6aae7bf4 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -3,24 +3,21 @@ - !record {model: mail.message.subtype, id: mail.mail_subtype_won }: name: won - model_ids: - - crm.model_crm_lead + res_model:crm.lead default: False - I have add the sub_type name email with default true - !record {model: mail.message.subtype, id: mail.mail_subtype_email }: name: email - model_ids: - - crm.model_crm_lead + res_model:crm.lead default: True - I have add the sub_type name comment with default true - !record {model: mail.message.subtype, id: mail.mail_subtype_comment }: name: comment - model_ids: - - crm.model_crm_lead + res_model:crm.lead default: True - I have add the subtypes as won in feeds From d5687b3ed0538d095cc8209c1de78de1a10448b6 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 16:15:18 +0530 Subject: [PATCH 209/726] [IMP]crm yml improve bzr revid: sgo@tinyerp.com-20120913104518-6cse5m221l8n5yc4 --- addons/crm/test/process/crm_message_subtype.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index 46c6aae7bf4..a1ad9a9c39a 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -3,22 +3,14 @@ - !record {model: mail.message.subtype, id: mail.mail_subtype_won }: name: won - res_model:crm.lead + res_model: crm.lead default: False -- - I have add the sub_type name email with default true -- - !record {model: mail.message.subtype, id: mail.mail_subtype_email }: - name: email - res_model:crm.lead - default: True - I have add the sub_type name comment with default true - !record {model: mail.message.subtype, id: mail.mail_subtype_comment }: name: comment - res_model:crm.lead - default: True + res_model: crm.lead - I have add the subtypes as won in feeds - From f554db5c6bc94b3e9fdf5aa67a0030cbb4026df2 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 17:10:44 +0530 Subject: [PATCH 210/726] [IMP]add subtype for crm_claim bzr revid: sgo@tinyerp.com-20120913114044-0spnm47pty5g04wu --- addons/crm_claim/crm_claim.py | 6 +++--- addons/crm_claim/crm_claim_data.xml | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index 535f6d20367..ce2427b9752 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -238,16 +238,16 @@ class crm_claim(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): msg = _('Claim has been created.') - return self.message_post(cr, uid, ids, body=msg, context=context) + return self.message_post(cr, uid, ids, body=msg, subtype_xml_id='claim_subtype_new', context=context) def case_refuse_send_note(self, cr, uid, ids, context=None): msg = _('Claim has been refused.') - return self.message_post(cr, uid, ids, body=msg, context=context) + return self.message_post(cr, uid, ids, body=msg, subtype_xml_id='claim_subtype_refused', context=context) def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.claim.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id='claim_subtype_stage_change', context=context) class res_partner(osv.osv): diff --git a/addons/crm_claim/crm_claim_data.xml b/addons/crm_claim/crm_claim_data.xml index 33bd280c364..a72c285f506 100644 --- a/addons/crm_claim/crm_claim_data.xml +++ b/addons/crm_claim/crm_claim_data.xml @@ -75,6 +75,32 @@ + + + + new + crm.claim + + + + refused + crm.claim + + + + stage change + crm.claim + + + cancelled + crm.claim + + + + closed + crm.claim + + From 2fbc7e9d046dcebea15b6a43289297e705984212 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Thu, 13 Sep 2012 17:21:38 +0530 Subject: [PATCH 211/726] [IMP]improve subtype in crm_claim bzr revid: sgo@tinyerp.com-20120913115138-4rrsmwmlfh4f25s1 --- addons/crm_claim/crm_claim_data.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/crm_claim/crm_claim_data.xml b/addons/crm_claim/crm_claim_data.xml index a72c285f506..e68bc3ad6cb 100644 --- a/addons/crm_claim/crm_claim_data.xml +++ b/addons/crm_claim/crm_claim_data.xml @@ -99,7 +99,6 @@ closed crm.claim - From 550751b35825d60af0ed5985cd46b4ff4e2d3d01 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 13 Sep 2012 16:29:20 +0200 Subject: [PATCH 212/726] [IMP] translations: wip, remove unnecessary code, support loading PO comments and storing them, split ir.translation view data in separate XML file bzr revid: odo@openerp.com-20120913142920-ggpeqth4s2wwqwd2 --- openerp/addons/base/__openerp__.py | 1 + openerp/addons/base/ir/ir.xml | 69 ------------- openerp/addons/base/ir/ir_translation.py | 123 ++++++++++++----------- openerp/addons/base/ir/ir_ui_view.py | 5 +- openerp/addons/base/module/module.py | 16 +-- openerp/service/web_services.py | 24 ----- openerp/tests/common.py | 1 - openerp/tests/test_xmlrpc.py | 5 - openerp/tools/translate.py | 61 ++++++----- 9 files changed, 98 insertions(+), 207 deletions(-) diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 937c9cbd20b..082cf260373 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -44,6 +44,7 @@ The kernel of OpenERP, needed for all installation. 'data/res.country.state.csv', 'ir/wizard/wizard_menu_view.xml', 'ir/ir.xml', + 'ir/ir_translation_view.xml', 'ir/ir_filters.xml', 'ir/ir_config_parameter_view.xml', 'ir/workflow/workflow_view.xml', diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index 29bb681981a..515d9641001 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -1147,75 +1147,6 @@ - - - - Translations - ir.translation - - - - - - - - - - - - - Translations - ir.translation - -
                    -
                    - -
                    - - - - - - - - - - - - - - - - - - -
                    -
                    -
                    - - Translations - ir.translation - - - - - - - - - - - - - Translated Terms - ir.translation - form - - - - - mail.message.subtype.tree mail.message.subtype - tree 10 - + @@ -23,42 +18,27 @@ mail.message.subtype.form mail.message.subtype - form
                    - - - - - - - + + +
                    - + Subtypes mail.message.subtype form tree,form - -

                    - Click to create a message subtype. -

                    - OpenERP's message subtype allows to ease and fasten the - subtype which helps to decrease over crowdy wall comments which displays - only those. -

                    -
                    - + From 9805c665c89784bdaa5234668ed79ca2280cb124 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 19 Sep 2012 13:40:47 +0200 Subject: [PATCH 224/726] [ADD] big bit on new import: pretty much everything but o2m bzr revid: xmo@openerp.com-20120919114047-w4paoim95oxr91zb --- openerp/addons/base/ir/__init__.py | 1 + openerp/addons/base/ir/ir_fields.py | 193 ++++ openerp/osv/fields.py | 42 +- openerp/osv/orm.py | 226 +++- .../tests/addons/test_impex/tests/__init__.py | 3 +- .../addons/test_impex/tests/test_load.py | 987 ++++++++++++++++++ openerp/tests/test_misc.py | 38 +- openerp/tools/misc.py | 34 + setup.py | 1 + 9 files changed, 1507 insertions(+), 18 deletions(-) create mode 100644 openerp/addons/base/ir/ir_fields.py create mode 100644 openerp/tests/addons/test_impex/tests/test_load.py diff --git a/openerp/addons/base/ir/__init__.py b/openerp/addons/base/ir/__init__.py index bc4f3eecfbf..ba8b785f39d 100644 --- a/openerp/addons/base/ir/__init__.py +++ b/openerp/addons/base/ir/__init__.py @@ -40,6 +40,7 @@ import wizard import ir_config_parameter import osv_memory_autovacuum import ir_mail_server +import ir_fields # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py new file mode 100644 index 00000000000..f73067c9f6c --- /dev/null +++ b/openerp/addons/base/ir/ir_fields.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +import functools +import operator +import warnings +from openerp.osv import orm, fields +from openerp.tools.translate import _ + +class ConversionNotFound(ValueError): pass + +class ir_fields_converter(orm.Model): + _name = 'ir.fields.converter' + + def to_field(self, cr, uid, model, column, fromtype=str, context=None): + """ Fetches a converter for the provided column object, from the + specified type. + + A converter is simply a callable taking a value of type ``fromtype`` + (or a composite of ``fromtype``, e.g. list or dict) and returning a + value acceptable for a write() on the column ``column``. + + By default, tries to get a method on itself with a name matching the + pattern ``_$fromtype_$column._type`` and returns it. + + :param cr: openerp cursor + :param uid: ID of user calling the converter + :param column: column object to generate a value for + :type column: :class:`fields._column` + :param type fromtype: type to convert to something fitting for ``column`` + :param context: openerp request context + :return: a function (fromtype -> column.write_type), if a converter is found + :rtype: Callable | None + """ + # FIXME: return None + converter = getattr( + self, '_%s_to_%s' % (fromtype.__name__, column._type)) + if not converter: return None + + return functools.partial( + converter, cr, uid, model, column, context=context) + + def _str_to_boolean(self, cr, uid, model, column, value, context=None): + return value.lower() not in ('', '0', 'false', 'off') + + def _str_to_integer(self, cr, uid, model, column, value, context=None): + if not value: return False + return int(value) + + def _str_to_float(self, cr, uid, model, column, value, context=None): + if not value: return False + return float(value) + + def _str_to_char(self, cr, uid, model, column, value, context=None): + return value or False + + def _str_to_text(self, cr, uid, model, column, value, context=None): + return value or False + + def _get_translations(self, cr, uid, types, src, context): + Translations = self.pool['ir.translation'] + tnx_ids = Translations.search( + cr, uid, [('type', 'in', types), ('src', '=', src)], context=context) + tnx = Translations.read(cr, uid, tnx_ids, ['value'], context=context) + return map(operator.itemgetter('value'), tnx) + def _str_to_selection(self, cr, uid, model, column, value, context=None): + + selection = column.selection + if not isinstance(selection, (tuple, list)): + # FIXME: Don't pass context to avoid translations? + # Or just copy context & remove lang? + selection = selection(model, cr, uid) + for item, label in selection: + labels = self._get_translations( + cr, uid, ('selection', 'model'), label, context=context) + labels.append(label) + if value == unicode(item) or value in labels: + return item + raise ValueError( + _(u"Value '%s' not found in selection field '%%(field)s'") % ( + value)) + + + def db_id_for(self, cr, uid, model, column, subfield, value, context=None): + """ Finds a database id for the reference ``value`` in the referencing + subfield ``subfield`` of the provided column of the provided model. + + :param cr: OpenERP cursor + :param uid: OpenERP user id + :param model: model to which the column belongs + :param column: relational column for which references are provided + :param subfield: a relational subfield allowing building of refs to + existing records: ``None`` for a name_get/name_search, + ``id`` for an external id and ``.id`` for a database + id + :param value: value of the reference to match to an actual record + :param context: OpenERP request context + :return: a pair of the matched database identifier (if any) and the + translated user-readable name for the field + :rtype: (ID|None, unicode) + """ + id = None + RelatedModel = self.pool[column._obj] + if subfield == '.id': + field_type = _(u"database id") + try: tentative_id = int(value) + except ValueError: tentative_id = value + if RelatedModel.search(cr, uid, [('id', '=', tentative_id)], + context=context): + id = tentative_id + elif subfield == 'id': + field_type = _(u"external id") + if '.' in value: + module, xid = value.split('.', 1) + else: + module, xid = '', value + ModelData = self.pool['ir.model.data'] + try: + md_id = ModelData._get_id(cr, uid, module, xid) + model_data = ModelData.read(cr, uid, [md_id], ['res_id'], + context=context) + if model_data: + id = model_data[0]['res_id'] + except ValueError: pass # leave id is None + elif subfield is None: + field_type = _(u"name") + ids = RelatedModel.name_search( + cr, uid, name=value, operator='=', context=context) + if ids: + if len(ids) > 1: + warnings.warn( + _(u"Found multiple matches for field '%%(field)s' (%d matches)") + % (len(ids)), orm.ImportWarning) + id, _name = ids[0] + else: + raise Exception(u"Unknown sub-field '%s'" % subfield) + return id, field_type + + def _referencing_subfield(self, record): + """ Checks the record for the subfields allowing referencing (an + existing record in an other table), errors out if it finds potential + conflicts (multiple referencing subfields) or non-referencing subfields + returns the name of the correct subfield. + + :param record: + :return: the record subfield to use for referencing + :rtype: str + """ + # Can import by name_get, external id or database id + allowed_fields = set([None, 'id', '.id']) + fieldset = set(record.iterkeys()) + if fieldset - allowed_fields: + raise ValueError( + _(u"Can not create Many-To-One records indirectly, import the field separately")) + if len(fieldset) > 1: + raise ValueError( + _(u"Ambiguous specification for field '%(field)s', only provide one of name, external id or database id")) + + # only one field left possible, unpack + [subfield] = fieldset + return subfield + + def _str_to_many2one(self, cr, uid, model, column, values, context=None): + # Should only be one record, unpack + [record] = values + + subfield = self._referencing_subfield(record) + + reference = record[subfield] + id, subfield_type = self.db_id_for( + cr, uid, model, column, subfield, reference, context=context) + + if id is None: + raise ValueError( + _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") + % {'field_type': subfield_type, 'value': reference}) + return id + def _str_to_many2many(self, cr, uid, model, column, value, context=None): + [record] = value + + subfield = self._referencing_subfield(record) + + ids = [] + for reference in record[subfield].split(','): + id, subfield_type = self.db_id_for( + cr, uid, model, column, subfield, reference, context=context) + if id is None: + raise ValueError( + _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") + % {'field_type': subfield_type, 'value': reference}) + ids.append(id) + + return [(6, 0, ids)] + def _str_to_one2many(self, cr, uid, model, column, value, context=None): + return value diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 037d2a90986..36c6600a7e5 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1588,19 +1588,32 @@ def field_to_dict(model, cr, user, field, context=None): class column_info(object): - """Struct containing details about an osv column, either one local to - its model, or one inherited via _inherits. + """ Struct containing details about an osv column, either one local to + its model, or one inherited via _inherits. - :attr name: name of the column - :attr column: column instance, subclass of osv.fields._column - :attr parent_model: if the column is inherited, name of the model - that contains it, None for local columns. - :attr parent_column: the name of the column containing the m2o - relationship to the parent model that contains - this column, None for local columns. - :attr original_parent: if the column is inherited, name of the original - parent model that contains it i.e in case of multilevel - inheritence, None for local columns. + .. attribute:: name + + name of the column + + .. attribute:: column + + column instance, subclass of :class:`_column` + + .. attribute:: parent_model + + if the column is inherited, name of the model that contains it, + ``None`` for local columns. + + .. attribute:: parent_column + + the name of the column containing the m2o relationship to the + parent model that contains this column, ``None`` for local columns. + + .. attribute:: original_parent + + if the column is inherited, name of the original parent model that + contains it i.e in case of multilevel inheritance, ``None`` for + local columns. """ def __init__(self, name, column, parent_model=None, parent_column=None, original_parent=None): self.name = name @@ -1609,5 +1622,10 @@ class column_info(object): self.parent_column = parent_column self.original_parent = original_parent + def __str__(self): + return '%s(%s, %s, %s, %s, %s)' % ( + self.__name__, self.name, self.column, + self.parent_model, self.parent_column, self.original_parent) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 9d3b92a3d31..57cc5823dd9 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -52,13 +52,17 @@ import re import simplejson import time import types + +import psycopg2 from lxml import etree +import warnings import fields import openerp import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.config import config +from openerp.tools.misc import CountingStream from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ from openerp import SUPERUSER_ID @@ -1242,7 +1246,7 @@ class BaseModel(object): * The last item is currently unused, with no specific semantics :param fields: list of fields to import - :param data: data to import + :param datas: data to import :param mode: 'init' or 'update' for record creation :param current_module: module name :param noupdate: flag for record creation @@ -1438,6 +1442,199 @@ class BaseModel(object): self._parent_store_compute(cr) return position, 0, 0, 0 + def load(self, cr, uid, fields, data, context=None): + """ + + :param cr: cursor for the request + :param int uid: ID of the user attempting the data import + :param fields: list of fields to import, at the same index as the corresponding data + :type fields: list(str) + :param data: row-major matrix of data to import + :type data: list(list(str)) + :param dict context: + :returns: + """ + cr.execute('SAVEPOINT model_load') + messages = [] + + fields = map(fix_import_export_id_paths, fields) + ModelData = self.pool['ir.model.data'] + + mode = 'init' + current_module = '' + noupdate = False + + ids = [] + for id, xid, record, info in self._convert_records(cr, uid, + self._extract_records(cr, uid, fields, data, + context=context, log=messages.append), + context=context, log=messages.append): + cr.execute('SAVEPOINT model_load_save') + try: + ids.append(ModelData._update(cr, uid, self._name, + current_module, record, mode=mode, xml_id=xid, + noupdate=noupdate, res_id=id, context=context)) + cr.execute('RELEASE SAVEPOINT model_load_save') + except psycopg2.Error, e: + # Failed to write, log to messages, rollback savepoint (to + # avoid broken transaction) and keep going + cr.execute('ROLLBACK TO SAVEPOINT model_load_save') + messages.append(dict(info, type="error", message=str(e))) + if any(message['type'] == 'error' for message in messages): + cr.execute('ROLLBACK TO SAVEPOINT model_load') + return False, messages + return ids, messages + def _extract_records(self, cr, uid, fields_, data, + context=None, log=lambda a: None): + """ Generates record dicts from the data iterable. + + The result is a generator of dicts mapping field names to raw + (unconverted, unvalidated) values. + + For relational fields, if sub-fields were provided the value will be + a list of sub-records + + The following sub-fields may be set on the record (by key): + * None is the name_get for the record (to use with name_create/name_search) + * "id" is the External ID for the record + * ".id" is the Database ID for the record + + :param ImportLogger logger: + """ + columns = dict((k, v.column) for k, v in self._all_columns.iteritems()) + # Fake columns to avoid special cases in extractor + columns[None] = fields.char('rec_name') + columns['id'] = fields.char('External ID') + columns['.id'] = fields.integer('Database ID') + + # m2o fields can't be on multiple lines so exclude them from the + # is_relational field rows filter, but special-case it later on to + # be handled with relational fields (as it can have subfields) + is_relational = lambda field: columns[field]._type in ('one2many', 'many2many', 'many2one') + get_o2m_values = itemgetter_tuple( + [index for index, field in enumerate(fields_) + if columns[field[0]]._type == 'one2many']) + get_nono2m_values = itemgetter_tuple( + [index for index, field in enumerate(fields_) + if columns[field[0]]._type != 'one2many']) + # Checks if the provided row has any non-empty non-relational field + def only_o2m_values(row, f=get_nono2m_values, g=get_o2m_values): + return any(g(row)) and not any(f(row)) + + rows = CountingStream(data) + while True: + row = next(rows, None) + if row is None: return + record_row_index = rows.index + + # copy non-relational fields to record dict + record = dict((field[0], value) + for field, value in itertools.izip(fields_, row) + if not is_relational(field[0])) + + # Get all following rows which have relational values attached to + # the current record (no non-relational values) + # WARNING: replaces existing ``rows`` + record_span, _rows = span(only_o2m_values, rows) + # stitch record row back on for relational fields + record_span = itertools.chain([row], record_span) + for relfield in set( + field[0] for field in fields_ + if is_relational(field[0])): + column = columns[relfield] + # FIXME: how to not use _obj without relying on fields_get? + Model = self.pool[column._obj] + + # copy stream to reuse for next relational field + fieldrows, record_span = itertools.tee(record_span) + # get only cells for this sub-field, should be strictly + # non-empty, field path [None] is for name_get column + indices, subfields = zip(*((index, field[1:] or [None]) + for index, field in enumerate(fields_) + if field[0] == relfield)) + + # return all rows which have at least one value for the + # subfields of relfield + relfield_data = filter(any, map(itemgetter_tuple(indices), fieldrows)) + record[relfield] = [subrecord + for subrecord, _subinfo in Model._extract_records( + cr, uid, subfields, relfield_data, + context=context, log=log)] + # Ensure full consumption of the span (and therefore advancement of + # ``rows``) even if there are no relational fields. Needs two as + # the code above stiched the row back on (so first call may only + # get the stiched row without advancing the underlying operator row + # itself) + next(record_span, None) + next(record_span, None) + + # old rows consumption (by iterating the span) should be done here, + # at this point the old ``rows`` is 1 past `span` (either on the + # next record row or past ``StopIteration``, so wrap new ``rows`` + # (``_rows``) in a counting stream indexed 1-before the old + # ``rows`` + rows = CountingStream(_rows, rows.index - 1) + yield record, {'rows': {'from': record_row_index,'to': rows.index}} + def _convert_records(self, cr, uid, records, + context=None, log=lambda a: None): + """ Converts records from the source iterable (recursive dicts of + strings) into forms which can be written to the database (via + self.create or (ir.model.data)._update) + + :param ImportLogger parent_logger: + :returns: a list of triplets of (id, xid, record) + :rtype: list((int|None, str|None, dict)) + """ + Converter = self.pool['ir.fields.converter'] + columns = dict((k, v.column) for k, v in self._all_columns.iteritems()) + converters = dict( + (k, Converter.to_field(cr, uid, self, column, context=context)) + for k, column in columns.iteritems()) + + stream = CountingStream(records) + for record, extras in stream: + dbid = False + xid = False + converted = {} + # name_get/name_create + if None in record: pass + # xid + if 'id' in record: + xid = record['id'] + # dbid + if '.id' in record: + try: + dbid = int(record['.id']) + except ValueError: + # in case of overridden id column + dbid = record['.id'] + if not self.search(cr, uid, [('id', '=', dbid)], context=context): + log(dict(extras, + type='error', + record=stream.index, + field='.id', + message=_(u"Unknown database identifier '%s'") % dbid)) + dbid = False + + for field, strvalue in record.iteritems(): + if field in (None, 'id', '.id'): continue + + message_base = dict(extras, record=stream.index, field=field) + with warnings.catch_warnings(record=True) as w: + try: + converted[field] = converters[field](strvalue) + + for warning in w: + log(dict(message_base, type='warning', + message=unicode(warning.message) % message_base)) + except ValueError, e: + log(dict(message_base, + type='error', + message=unicode(e) % message_base + )) + + yield dbid, xid, converted, dict(extras, record=stream.index) + def get_invalid_fields(self, cr, uid): return list(self._invalids) @@ -5108,5 +5305,32 @@ class AbstractModel(BaseModel): _auto = False # don't create any database backend for AbstractModels _register = False # not visible in ORM registry, meant to be python-inherited only +def span(predicate, iterable): + """ Splits the iterable between the longest prefix of ``iterable`` whose + elements satisfy ``predicate`` and the rest. + If called with a list, equivalent to:: + + takewhile(predicate, lst), dropwhile(predicate, lst) + + :param callable predicate: + :param iterable: + :rtype: (iterable, iterable) + """ + it1, it2 = itertools.tee(iterable) + return (itertools.takewhile(predicate, it1), + itertools.dropwhile(predicate, it2)) +def itemgetter_tuple(items): + """ Fixes itemgetter inconsistency (useful in some cases) of not returning + a tuple if len(items) == 1: always returns an n-tuple where n = len(items) + """ + if len(items) == 0: + return lambda a: () + if len(items) == 1: + return lambda gettable: (gettable[items[0]],) + return operator.itemgetter(*items) +class ImportWarning(Warning): + """ Used to send warnings upwards the stack during the import process + """ + pass # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/addons/test_impex/tests/__init__.py b/openerp/tests/addons/test_impex/tests/__init__.py index d6af53cba1b..8cab56fcc9a 100644 --- a/openerp/tests/addons/test_impex/tests/__init__.py +++ b/openerp/tests/addons/test_impex/tests/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from . import test_export, test_import +from . import test_export, test_import, test_load fast_suite = [ ] @@ -8,6 +8,7 @@ fast_suite = [ checks = [ test_export, test_import, + test_load, ] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py new file mode 100644 index 00000000000..80e5cfe9c8f --- /dev/null +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -0,0 +1,987 @@ +# -*- coding: utf-8 -*- +import openerp.modules.registry +import openerp + +from openerp.tests import common +from openerp.tools.misc import mute_logger + +def message(msg, type='error', from_=0, to_=0, record=0, field='value'): + return { + 'type': type, + 'rows': {'from': from_, 'to': to_}, + 'record': record, + 'field': field, + 'message': msg + } + +def error(row, message, record=None, **kwargs): + """ Failed import of the record ``record`` at line ``row``, with the error + message ``message`` + + :param str message: + :param dict record: + """ + return ( + -1, dict(record or {}, **kwargs), + "Line %d : %s" % (row, message), + '') + +def values(seq, field='value'): + return [item[field] for item in seq] + +class ImporterCase(common.TransactionCase): + model_name = False + + def __init__(self, *args, **kwargs): + super(ImporterCase, self).__init__(*args, **kwargs) + self.model = None + + def setUp(self): + super(ImporterCase, self).setUp() + self.model = self.registry(self.model_name) + self.registry('ir.model.data').clear_caches() + + def import_(self, fields, rows, context=None): + return self.model.load( + self.cr, openerp.SUPERUSER_ID, fields, rows, context=context) + def read(self, fields=('value',), domain=(), context=None): + return self.model.read( + self.cr, openerp.SUPERUSER_ID, + self.model.search(self.cr, openerp.SUPERUSER_ID, domain, context=context), + fields=fields, context=context) + def browse(self, domain=(), context=None): + return self.model.browse( + self.cr, openerp.SUPERUSER_ID, + self.model.search(self.cr, openerp.SUPERUSER_ID, domain, context=context), + context=context) + + def xid(self, record): + ModelData = self.registry('ir.model.data') + + ids = ModelData.search( + self.cr, openerp.SUPERUSER_ID, + [('model', '=', record._table_name), ('res_id', '=', record.id)]) + if ids: + d = ModelData.read( + self.cr, openerp.SUPERUSER_ID, ids, ['name', 'module'])[0] + if d['module']: + return '%s.%s' % (d['module'], d['name']) + return d['name'] + + name = dict(record.name_get())[record.id] + # fix dotted name_get results, otherwise xid lookups blow up + name = name.replace('.', '-') + ModelData.create(self.cr, openerp.SUPERUSER_ID, { + 'name': name, + 'model': record._table_name, + 'res_id': record.id, + 'module': '__test__' + }) + return '__test__.' + name + +class test_ids_stuff(ImporterCase): + model_name = 'export.integer' + + def test_create_with_id(self): + ids, messages = self.import_(['.id', 'value'], [['42', '36']]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'field': '.id', + 'message': u"Unknown database identifier '42'", + }]) + def test_create_with_xid(self): + ids, messages = self.import_(['id', 'value'], [['somexmlid', '42']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual( + 'somexmlid', + self.xid(self.browse()[0])) + + def test_update_with_id(self): + id = self.model.create(self.cr, openerp.SUPERUSER_ID, {'value': 36}) + self.assertEqual( + 36, + self.model.browse(self.cr, openerp.SUPERUSER_ID, id).value) + + ids, messages = self.import_(['.id', 'value'], [[str(id), '42']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual( + [42], # updated value to imported + values(self.read())) + + def test_update_with_xid(self): + self.import_(['id', 'value'], [['somexmlid', '36']]) + self.assertEqual([36], values(self.read())) + + self.import_(['id', 'value'], [['somexmlid', '1234567']]) + self.assertEqual([1234567], values(self.read())) + +class test_boolean_field(ImporterCase): + model_name = 'export.boolean' + + def test_empty(self): + self.assertEqual( + self.import_(['value'], []), + ([], [])) + + def test_exported(self): + ids, messages = self.import_(['value'], [['False'], ['True'], ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + records = self.read() + self.assertEqual([ + False, + True, + ], values(records)) + + def test_falses(self): + ids, messages = self.import_( + ['value'], + [[u'0'], [u'off'], + [u'false'], [u'FALSE'], + [u'OFF'], [u''], + ]) + self.assertEqual(len(ids), 6) + self.assertFalse(messages) + self.assertEqual([ + False, + False, + False, + False, + False, + False, + ], + values(self.read())) + + def test_trues(self): + ids, messages = self.import_( + ['value'], + [['no'], + ['None'], + ['nil'], + ['()'], + ['f'], + ['#f'], + # Problem: OpenOffice (and probably excel) output localized booleans + ['VRAI'], + ]) + self.assertEqual(len(ids), 7) + # FIXME: should warn for values which are not "true", "yes" or "1" + self.assertFalse(messages) + self.assertEqual( + [True] * 7, + values(self.read())) + +class test_integer_field(ImporterCase): + model_name = 'export.integer' + + def test_none(self): + self.assertEqual( + self.import_(['value'], []), + ([], [])) + + def test_empty(self): + ids, messages = self.import_(['value'], [['']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual( + [False], + values(self.read())) + + def test_zero(self): + ids, messages = self.import_(['value'], [['0']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + ids, messages = self.import_(['value'], [['-0']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + self.assertEqual([False, False], values(self.read())) + + def test_positives(self): + ids, messages = self.import_(['value'], [ + ['1'], + ['42'], + [str(2**31-1)], + ['12345678'] + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + + self.assertEqual([ + 1, 42, 2**31-1, 12345678 + ], values(self.read())) + + def test_negatives(self): + ids, messages = self.import_(['value'], [ + ['-1'], + ['-42'], + [str(-(2**31 - 1))], + [str(-(2**31))], + ['-12345678'] + ]) + self.assertEqual(len(ids), 5) + self.assertFalse(messages) + self.assertEqual([ + -1, -42, -(2**31 - 1), -(2**31), -12345678 + ], values(self.read())) + + @mute_logger('openerp.sql_db') + def test_out_of_range(self): + ids, messages = self.import_(['value'], [[str(2**31)]]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'message': "integer out of range\n" + }]) + + ids, messages = self.import_(['value'], [[str(-2**32)]]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'message': "integer out of range\n" + }]) + + def test_nonsense(self): + ids, messages = self.import_(['value'], [['zorglub']]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'field': 'value', + 'message': u"invalid literal for int() with base 10: 'zorglub'", + }]) + +class test_float_field(ImporterCase): + model_name = 'export.float' + def test_none(self): + self.assertEqual( + self.import_(['value'], []), + ([], [])) + + def test_empty(self): + ids, messages = self.import_(['value'], [['']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual( + [False], + values(self.read())) + + def test_zero(self): + ids, messages = self.import_(['value'], [['0']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + ids, messages = self.import_(['value'], [['-0']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + self.assertEqual([False, False], values(self.read())) + + def test_positives(self): + ids, messages = self.import_(['value'], [ + ['1'], + ['42'], + [str(2**31-1)], + ['12345678'], + [str(2**33)], + ['0.000001'], + ]) + self.assertEqual(len(ids), 6) + self.assertFalse(messages) + + self.assertEqual([ + 1, 42, 2**31-1, 12345678, 2.0**33, .000001 + ], values(self.read())) + + def test_negatives(self): + ids, messages = self.import_(['value'], [ + ['-1'], + ['-42'], + [str(-2**31 + 1)], + [str(-2**31)], + ['-12345678'], + [str(-2**33)], + ['-0.000001'], + ]) + self.assertEqual(len(ids), 7) + self.assertFalse(messages) + self.assertEqual([ + -1, -42, -(2**31 - 1), -(2**31), -12345678, -2.0**33, -.000001 + ], values(self.read())) + + def test_nonsense(self): + ids, messages = self.import_(['value'], [['foobar']]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'field': 'value', + 'message': u"invalid literal for float(): foobar", + }]) + +class test_string_field(ImporterCase): + model_name = 'export.string.bounded' + + def test_empty(self): + ids, messages = self.import_(['value'], [['']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual([False], values(self.read())) + + def test_imported(self): + ids, messages = self.import_(['value'], [ + [u'foobar'], + [u'foobarbaz'], + [u'Með suð í eyrum við spilum endalaust'], + [u"People 'get' types. They use them all the time. Telling " + u"someone he can't pound a nail with a banana doesn't much " + u"surprise him."] + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + self.assertEqual([ + u"foobar", + u"foobarbaz", + u"Með suð í eyrum ", + u"People 'get' typ", + ], values(self.read())) + +class test_unbound_string_field(ImporterCase): + model_name = 'export.string' + + def test_imported(self): + ids, messages = self.import_(['value'], [ + [u'í dag viðrar vel til loftárása'], + # ackbar.jpg + [u"If they ask you about fun, you tell them – fun is a filthy" + u" parasite"] + ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + self.assertEqual([ + u"í dag viðrar vel til loftárása", + u"If they ask you about fun, you tell them – fun is a filthy parasite" + ], values(self.read())) + +class test_text(ImporterCase): + model_name = 'export.text' + + def test_empty(self): + ids, messages = self.import_(['value'], [['']]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual([False], values(self.read())) + + def test_imported(self): + s = (u"Breiðskífa er notað um útgefna hljómplötu sem inniheldur " + u"stúdíóupptökur frá einum flytjanda. Breiðskífur eru oftast " + u"milli 25-80 mínútur og er lengd þeirra oft miðuð við 33⅓ " + u"snúninga 12 tommu vínylplötur (sem geta verið allt að 30 mín " + u"hvor hlið).\n\nBreiðskífur eru stundum tvöfaldar og eru þær þá" + u" gefnar út á tveimur geisladiskum eða tveimur vínylplötum.") + ids, messages = self.import_(['value'], [[s]]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + self.assertEqual([s], values(self.read())) + +class test_selection(ImporterCase): + model_name = 'export.selection' + translations_fr = [ + ("Qux", "toto"), + ("Bar", "titi"), + ("Foo", "tete"), + ] + + def test_imported(self): + ids, messages = self.import_(['value'], [ + ['Qux'], + ['Bar'], + ['Foo'], + ['2'], + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + self.assertEqual([3, 2, 1, 2], values(self.read())) + + def test_imported_translated(self): + self.registry('res.lang').create(self.cr, openerp.SUPERUSER_ID, { + 'name': u'Français', + 'code': 'fr_FR', + 'translatable': True, + 'date_format': '%d.%m.%Y', + 'decimal_point': ',', + 'thousand_sep': ' ', + }) + Translations = self.registry('ir.translation') + for source, value in self.translations_fr: + Translations.create(self.cr, openerp.SUPERUSER_ID, { + 'name': 'export.selection,value', + 'lang': 'fr_FR', + 'type': 'selection', + 'src': source, + 'value': value + }) + + ids, messages = self.import_(['value'], [ + ['toto'], + ['tete'], + ['titi'], + ], context={'lang': 'fr_FR'}) + self.assertEqual(len(ids), 3) + self.assertFalse(messages) + + self.assertEqual([3, 1, 2], values(self.read())) + + ids, messages = self.import_(['value'], [['Foo']], context={'lang': 'fr_FR'}) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + def test_invalid(self): + ids, messages = self.import_(['value'], [['Baz']]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'field': 'value', + 'message': "Value 'Baz' not found in selection field 'value'", + }]) + + ids, messages = self.import_(['value'], [[42]]) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 0, 'to': 0}, + 'record': 0, + 'field': 'value', + 'message': "Value '42' not found in selection field 'value'", + }]) + +class test_selection_function(ImporterCase): + model_name = 'export.selection.function' + translations_fr = [ + ("Corge", "toto"), + ("Grault", "titi"), + ("Whee", "tete"), + ("Moog", "tutu"), + ] + + def test_imported(self): + """ import uses fields_get, so translates import label (may or may not + be good news) *and* serializes the selection function to reverse it: + import does not actually know that the selection field uses a function + """ + # NOTE: conflict between a value and a label => ? + ids, messages = self.import_(['value'], [ + ['3'], + ["Grault"], + ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + self.assertEqual( + ['3', '1'], + values(self.read())) + + def test_translated(self): + """ Expects output of selection function returns translated labels + """ + self.registry('res.lang').create(self.cr, openerp.SUPERUSER_ID, { + 'name': u'Français', + 'code': 'fr_FR', + 'translatable': True, + 'date_format': '%d.%m.%Y', + 'decimal_point': ',', + 'thousand_sep': ' ', + }) + Translations = self.registry('ir.translation') + for source, value in self.translations_fr: + Translations.create(self.cr, openerp.SUPERUSER_ID, { + 'name': 'export.selection,value', + 'lang': 'fr_FR', + 'type': 'selection', + 'src': source, + 'value': value + }) + ids, messages = self.import_(['value'], [ + ['toto'], + ['tete'], + ], context={'lang': 'fr_FR'}) + self.assertIs(ids, False) + self.assertEqual(messages, [{ + 'type': 'error', + 'rows': {'from': 1, 'to': 1}, + 'record': 1, + 'field': 'value', + 'message': "Value 'tete' not found in selection field 'value'", + }]) + ids, messages = self.import_(['value'], [['Wheee']], context={'lang': 'fr_FR'}) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + +class test_m2o(ImporterCase): + model_name = 'export.many2one' + + def test_by_name(self): + # create integer objects + integer_id1 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + integer_id2 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 36}) + # get its name + name1 = dict(self.registry('export.integer').name_get( + self.cr, openerp.SUPERUSER_ID,[integer_id1]))[integer_id1] + name2 = dict(self.registry('export.integer').name_get( + self.cr, openerp.SUPERUSER_ID,[integer_id2]))[integer_id2] + + ids , messages = self.import_(['value'], [ + # import by name_get + [name1], + [name1], + [name2], + ]) + self.assertFalse(messages) + self.assertEqual(len(ids), 3) + # correct ids assigned to corresponding records + self.assertEqual([ + (integer_id1, name1), + (integer_id1, name1), + (integer_id2, name2),], + values(self.read())) + + def test_by_xid(self): + ExportInteger = self.registry('export.integer') + integer_id = ExportInteger.create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + xid = self.xid(ExportInteger.browse( + self.cr, openerp.SUPERUSER_ID, [integer_id])[0]) + + ids, messages = self.import_(['value/id'], [[xid]]) + self.assertFalse(messages) + self.assertEqual(len(ids), 1) + b = self.browse() + self.assertEqual(42, b[0].value.value) + + def test_by_id(self): + integer_id = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + ids, messages = self.import_(['value/.id'], [[integer_id]]) + self.assertFalse(messages) + self.assertEqual(len(ids), 1) + b = self.browse() + self.assertEqual(42, b[0].value.value) + + def test_by_names(self): + integer_id1 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + integer_id2 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + name1 = dict(self.registry('export.integer').name_get( + self.cr, openerp.SUPERUSER_ID,[integer_id1]))[integer_id1] + name2 = dict(self.registry('export.integer').name_get( + self.cr, openerp.SUPERUSER_ID,[integer_id2]))[integer_id2] + # names should be the same + self.assertEqual(name1, name2) + + ids, messages = self.import_(['value'], [[name2]]) + self.assertEqual( + messages, + [message(u"Found multiple matches for field 'value' (2 matches)", + type='warning')]) + self.assertEqual(len(ids), 1) + self.assertEqual([ + (integer_id1, name1) + ], values(self.read())) + + def test_fail_by_implicit_id(self): + """ Can't implicitly import records by id + """ + # create integer objects + integer_id1 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 42}) + integer_id2 = self.registry('export.integer').create( + self.cr, openerp.SUPERUSER_ID, {'value': 36}) + + # Because name_search all the things. Fallback schmallback + ids, messages = self.import_(['value'], [ + # import by id, without specifying it + [integer_id1], + [integer_id2], + [integer_id1], + ]) + self.assertEqual(messages, [ + message(u"No matching record found for name '%s' in field 'value'" % id, + from_=index, to_=index, record=index) + for index, id in enumerate([integer_id1, integer_id2, integer_id1])]) + self.assertIs(ids, False) + + def test_sub_field(self): + """ Does not implicitly create the record, does not warn that you can't + import m2o subfields (at all)... + """ + ids, messages = self.import_(['value/value'], [['42']]) + self.assertEqual(messages, [ + message(u"Can not create Many-To-One records indirectly, import " + u"the field separately")]) + self.assertIs(ids, False) + + def test_fail_noids(self): + ids, messages = self.import_(['value'], [['nameisnoexist:3']]) + self.assertEqual(messages, [message( + u"No matching record found for name 'nameisnoexist:3' " + u"in field 'value'")]) + self.assertIs(ids, False) + + ids, messages = self.import_(['value/id'], [['noxidhere']]) + self.assertEqual(messages, [message( + u"No matching record found for external id 'noxidhere' " + u"in field 'value'")]) + self.assertIs(ids, False) + + ids, messages = self.import_(['value/.id'], [['66']]) + self.assertEqual(messages, [message( + u"No matching record found for database id '66' " + u"in field 'value'")]) + self.assertIs(ids, False) + + def test_fail_multiple(self): + ids, messages = self.import_( + ['value', 'value/id'], + [['somename', 'somexid']]) + self.assertEqual(messages, [message( + u"Ambiguous specification for field 'value', only provide one of " + u"name, external id or database id")]) + self.assertIs(ids, False) + +class test_m2m(ImporterCase): + model_name = 'export.many2many' + + # apparently, one and only thing which works is a + # csv_internal_sep-separated list of ids, xids, or names (depending if + # m2m/.id, m2m/id or m2m[/anythingelse] + def test_ids(self): + id1 = self.registry('export.many2many.other').create( + self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) + id2 = self.registry('export.many2many.other').create( + self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) + id3 = self.registry('export.many2many.other').create( + self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) + id4 = self.registry('export.many2many.other').create( + self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) + id5 = self.registry('export.many2many.other').create( + self.cr, openerp.SUPERUSER_ID, {'value': 99, 'str': 'record4'}) + + ids, messages = self.import_(['value/.id'], [ + ['%d,%d' % (id1, id2)], + ['%d,%d,%d' % (id1, id3, id4)], + ['%d,%d,%d' % (id1, id2, id3)], + ['%d' % id5] + ]) + self.assertFalse(messages) + self.assertEqual(len(ids), 4) + + ids = lambda records: [record.id for record in records] + + b = self.browse() + self.assertEqual(ids(b[0].value), [id1, id2]) + self.assertEqual(values(b[0].value), [3, 44]) + + self.assertEqual(ids(b[2].value), [id1, id2, id3]) + self.assertEqual(values(b[2].value), [3, 44, 84]) + + def test_noids(self): + ids, messages = self.import_(['value/.id'], [['42']]) + self.assertEqual(messages, [message( + u"No matching record found for database id '42' in field " + u"'value'")]) + self.assertIs(ids, False) + + def test_xids(self): + M2O_o = self.registry('export.many2many.other') + id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) + id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) + id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) + id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) + records = M2O_o.browse(self.cr, openerp.SUPERUSER_ID, [id1, id2, id3, id4]) + + ids, messages = self.import_(['value/id'], [ + ['%s,%s' % (self.xid(records[0]), self.xid(records[1]))], + ['%s' % self.xid(records[3])], + ['%s,%s' % (self.xid(records[2]), self.xid(records[1]))], + ]) + self.assertFalse(messages) + self.assertEqual(len(ids), 3) + + b = self.browse() + self.assertEqual(values(b[0].value), [3, 44]) + self.assertEqual(values(b[2].value), [44, 84]) + def test_noxids(self): + ids, messages = self.import_(['value/id'], [['noxidforthat']]) + self.assertEqual(messages, [message( + u"No matching record found for external id 'noxidforthat' " + u"in field 'value'")]) + self.assertIs(ids, False) + + def test_names(self): + M2O_o = self.registry('export.many2many.other') + id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) + id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) + id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) + id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) + records = M2O_o.browse(self.cr, openerp.SUPERUSER_ID, [id1, id2, id3, id4]) + + name = lambda record: dict(record.name_get())[record.id] + + ids, messages = self.import_(['value'], [ + ['%s,%s' % (name(records[1]), name(records[2]))], + ['%s,%s,%s' % (name(records[0]), name(records[1]), name(records[2]))], + ['%s,%s' % (name(records[0]), name(records[3]))], + ]) + self.assertFalse(messages) + self.assertEqual(len(ids), 3) + + b = self.browse() + self.assertEqual(values(b[1].value), [3, 44, 84]) + self.assertEqual(values(b[2].value), [3, 9]) + + def test_nonames(self): + ids, messages = self.import_(['value'], [['wherethem2mhavenonames']]) + self.assertEqual(messages, [message( + u"No matching record found for name 'wherethem2mhavenonames' in " + u"field 'value'")]) + self.assertIs(ids, False) + + def test_import_to_existing(self): + M2O_o = self.registry('export.many2many.other') + id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) + id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) + id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) + id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) + + xid = 'myxid' + ids, messages = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id1, id2)]]) + self.assertFalse(messages) + self.assertEqual(len(ids), 1) + ids, messages = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id3, id4)]]) + self.assertFalse(messages) + self.assertEqual(len(ids), 1) + + b = self.browse() + self.assertEqual(len(b), 1) + # TODO: replacement of existing m2m values is correct? + self.assertEqual(values(b[0].value), [84, 9]) + +class test_o2m(ImporterCase): + model_name = 'export.one2many' + + def test_name_get(self): + # FIXME: bloody hell why can't this just name_create the record? + self.assertRaises( + IndexError, + self.import_, + ['const', 'value'], + [['5', u'Java is a DSL for taking large XML files' + u' and converting them to stack traces']]) + + def test_single(self): + ids, messages = self.import_(['const', 'value/value'], [ + ['5', '63'] + ]) + self.assertEqual(len(ids), 1) + self.assertFalse(messages) + + (b,) = self.browse() + self.assertEqual(b.const, 5) + self.assertEqual(values(b.value), [63]) + + def test_multicore(self): + ids, messages = self.import_(['const', 'value/value'], [ + ['5', '63'], + ['6', '64'], + ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + + b1, b2 = self.browse() + self.assertEqual(b1.const, 5) + self.assertEqual(values(b1.value), [63]) + self.assertEqual(b2.const, 6) + self.assertEqual(values(b2.value), [64]) + + def test_multisub(self): + ids, messages = self.import_(['const', 'value/value'], [ + ['5', '63'], + ['', '64'], + ['', '65'], + ['', '66'], + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + + (b,) = self.browse() + self.assertEqual(values(b.value), [63, 64, 65, 66]) + + def test_multi_subfields(self): + ids, messages = self.import_(['value/str', 'const', 'value/value'], [ + ['this', '5', '63'], + ['is', '', '64'], + ['the', '', '65'], + ['rhythm', '', '66'], + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + + (b,) = self.browse() + self.assertEqual(values(b.value), [63, 64, 65, 66]) + self.assertEqual( + values(b.value, 'str'), + 'this is the rhythm'.split()) + + def test_link_inline(self): + id1 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Bf', 'value': 109 + }) + id2 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Me', 'value': 262 + }) + + try: + self.import_(['const', 'value/.id'], [ + ['42', '%d,%d' % (id1, id2)] + ]) + self.fail("Should have raised a valueerror") + except ValueError, e: + # should be Exception(Database ID doesn't exist: export.one2many.child : $id1,$id2) + self.assertIs(type(e), ValueError) + self.assertEqual( + e.args[0], + "invalid literal for int() with base 10: '%d,%d'" % (id1, id2)) + + def test_link(self): + id1 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Bf', 'value': 109 + }) + id2 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Me', 'value': 262 + }) + + ids, messages = self.import_(['const', 'value/.id'], [ + ['42', str(id1)], + ['', str(id2)], + ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + + # No record values alongside id => o2m resolution skipped altogether, + # creates 2 records => remove/don't import columns sideshow columns, + # get completely different semantics + b, b1 = self.browse() + self.assertEqual(b.const, 42) + self.assertEqual(values(b.value), []) + self.assertEqual(b1.const, 4) + self.assertEqual(values(b1.value), []) + + def test_link_2(self): + O2M_c = self.registry('export.one2many.child') + id1 = O2M_c.create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Bf', 'value': 109 + }) + id2 = O2M_c.create(self.cr, openerp.SUPERUSER_ID, { + 'str': 'Me', 'value': 262 + }) + + ids, messages = self.import_(['const', 'value/.id', 'value/value'], [ + ['42', str(id1), '1'], + ['', str(id2), '2'], + ]) + self.assertEqual(len(ids), 2) + self.assertFalse(messages) + + (b,) = self.browse() + # if an id (db or xid) is provided, expectations that objects are + # *already* linked and emits UPDATE (1, id, {}). + # Noid => CREATE (0, ?, {}) + # TODO: xid ignored aside from getting corresponding db id? + self.assertEqual(b.const, 42) + self.assertEqual(values(b.value), []) + + # FIXME: updates somebody else's records? + self.assertEqual( + O2M_c.read(self.cr, openerp.SUPERUSER_ID, id1), + {'id': id1, 'str': 'Bf', 'value': 1, 'parent_id': False}) + self.assertEqual( + O2M_c.read(self.cr, openerp.SUPERUSER_ID, id2), + {'id': id2, 'str': 'Me', 'value': 2, 'parent_id': False}) + +class test_o2m_multiple(ImporterCase): + model_name = 'export.one2many.multiple' + + def test_multi_mixed(self): + ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + ['5', '11', '21'], + ['', '12', '22'], + ['', '13', '23'], + ['', '14', ''], + ]) + self.assertEqual(len(ids), 4) + self.assertFalse(messages) + # Oh yeah, that's the stuff + (b, b1, b2) = self.browse() + self.assertEqual(values(b.child1), [11]) + self.assertEqual(values(b.child2), [21]) + + self.assertEqual(values(b1.child1), [12]) + self.assertEqual(values(b1.child2), [22]) + + self.assertEqual(values(b2.child1), [13, 14]) + self.assertEqual(values(b2.child2), [23]) + + def test_multi(self): + ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + ['5', '11', '21'], + ['', '12', ''], + ['', '13', ''], + ['', '14', ''], + ['', '', '22'], + ['', '', '23'], + ]) + self.assertEqual(len(ids), 6) + self.assertFalse(messages) + # What the actual fuck? + (b, b1) = self.browse() + self.assertEqual(values(b.child1), [11, 12, 13, 14]) + self.assertEqual(values(b.child2), [21]) + self.assertEqual(values(b1.child2), [22, 23]) + + def test_multi_fullsplit(self): + ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + ['5', '11', ''], + ['', '12', ''], + ['', '13', ''], + ['', '14', ''], + ['', '', '21'], + ['', '', '22'], + ['', '', '23'], + ]) + self.assertEqual(len(ids), 7) + self.assertFalse(messages) + # oh wow + (b, b1) = self.browse() + self.assertEqual(b.const, 5) + self.assertEqual(values(b.child1), [11, 12, 13, 14]) + self.assertEqual(b1.const, 36) + self.assertEqual(values(b1.child2), [21, 22, 23]) + +# function, related, reference: written to db as-is... +# => function uses @type for value coercion/conversion diff --git a/openerp/tests/test_misc.py b/openerp/tests/test_misc.py index 7661f253b17..54ae69899a6 100644 --- a/openerp/tests/test_misc.py +++ b/openerp/tests/test_misc.py @@ -2,12 +2,12 @@ # > PYTHONPATH=. python2 openerp/tests/test_misc.py import unittest2 +from ..tools import misc -class test_misc(unittest2.TestCase): +class append_content_to_html(unittest2.TestCase): """ Test some of our generic utility functions """ def test_append_to_html(self): - from openerp.tools import append_content_to_html test_samples = [ ('some content', '--\nYours truly', True, 'some content\n
                    --\nYours truly
                    \n'), @@ -15,7 +15,37 @@ class test_misc(unittest2.TestCase): 'some content\n\n\n

                    --

                    \n

                    Yours truly

                    \n\n\n'), ] for html, content, flag, expected in test_samples: - self.assertEqual(append_content_to_html(html,content,flag), expected, 'append_content_to_html is broken') + self.assertEqual(misc.append_content_to_html(html,content,flag), expected, 'append_content_to_html is broken') + +class test_countingstream(unittest2.TestCase): + def test_empty_stream(self): + s = misc.CountingStream(iter([])) + self.assertEqual(s.index, -1) + self.assertIsNone(next(s, None)) + self.assertEqual(s.index, 0) + + def test_single(self): + s = misc.CountingStream(xrange(1)) + self.assertEqual(s.index, -1) + self.assertEqual(next(s, None), 0) + self.assertIsNone(next(s, None)) + self.assertEqual(s.index, 1) + + def test_full(self): + s = misc.CountingStream(xrange(42)) + for _ in s: + pass + self.assertEqual(s.index, 42) + + def test_repeated(self): + """ Once the CountingStream has stopped iterating, the index should not + increase anymore (the internal state should not be allowed to change) + """ + s = misc.CountingStream(iter([])) + self.assertIsNone(next(s, None)) + self.assertEqual(s.index, 0) + self.assertIsNone(next(s, None)) + self.assertEqual(s.index, 0) if __name__ == '__main__': - unittest2.main() \ No newline at end of file + unittest2.main() diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 9a7b3499425..1ee3caf98d9 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -1220,4 +1220,38 @@ class mute_logger(object): with self: return func(*args, **kwargs) return deco + +_ph = object() +class CountingStream(object): + """ Stream wrapper counting the number of element it has yielded. Similar + role to ``enumerate``, but for use when the iteration process of the stream + isn't fully under caller control (the stream can be iterated from multiple + points including within a library) + + ``start`` allows overriding the starting index (the index before the first + item is returned). + + On each iteration (call to :meth:`~.next`), increases its :attr:`~.index` + by one. + + .. attribute:: index + + ``int``, index of the last yielded element in the stream. If the stream + has ended, will give an index 1-past the stream + """ + def __init__(self, stream, start=-1): + self.stream = iter(stream) + self.index = start + self.stopped = False + def __iter__(self): + return self + def next(self): + if self.stopped: raise StopIteration() + self.index += 1 + val = next(self.stream, _ph) + if val is _ph: + self.stopped = True + raise StopIteration() + return val + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/setup.py b/setup.py index a26b74e255d..4451bc1b710 100755 --- a/setup.py +++ b/setup.py @@ -116,6 +116,7 @@ setuptools.setup( extras_require = { 'SSL' : ['pyopenssl'], }, + tests_require = ['unittest2'], **py2exe_options() ) From 64672b176447c662408e853f5980a0f8f6c6f675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Sep 2012 13:43:53 +0200 Subject: [PATCH 225/726] [CLEAN] mail: comment xml_id is now mt_comment. Propagated change. Slighty cleaned code in base_status. bzr revid: tde@openerp.com-20120919114353-8s9lo6tp78tnwj56 --- addons/base_status/base_stage.py | 27 +++++++++---------- .../crm/test/process/crm_message_subtype.yml | 2 +- addons/mail/data/mail_data.xml | 2 +- addons/mail/mail_thread.py | 4 +-- addons/mail/tests/test_mail.py | 2 +- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 2695567e0a1..859e577bf31 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -349,6 +349,15 @@ class base_stage(object): """ return '' + def find_subtype_xml_id(self, cr, uid, ids, name, context=None): + ir_model_data_obj = self.pool.get('ir.model.data') + subtype_ids = self.pool.get('mail.message.subtype').search(cr, uid, [('res_model', '=', self._name), ('name', '=', name)], context=context) + ir_data_ids = ir_model_data_obj.search(cr, uid, [('model', '=', 'mail.message.subtype'), ('res_id', 'in', subtype_ids)], context=context) + ir_model_data_record = ir_model_data_obj.browse(cr, uid, ir_data_ids, context=context) + if ir_model_data_record: + return ir_model_data_record[0].name + return None + def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Send a notification when the stage changes. This method has to be overriden, because each document will have its particular @@ -360,31 +369,21 @@ class base_stage(object): def case_open_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been opened.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_post(cr, uid, [id], body=msg, context=context) + xml_id = self.find_subtype_xml_id(cr, uid, ids, name="open", context=context) + self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True - - def find_xml_id(self,cr,uid,ids,name,context=None): - subtype_obj = self.pool.get('mail.message.subtype') - ir_model_data_obj = self.pool.get('ir.model.data') - subtype_ids = subtype_obj.search(cr,uid,[('res_model','=',self._name),('name','=',name)]) - ir_data_ids = ir_model_data_obj.search(cr,uid,[('model','=','mail.message.subtype'),('res_id','in',subtype_ids)]) - xml_id = 'mail_subtype_comment' - ir_model_data_record = ir_model_data_obj.browse(cr,uid,ir_data_ids) - if ir_model_data_record: - xml_id = ir_model_data_record[0].name - return xml_id def case_close_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been closed.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - xml_id = self.find_xml_id(cr, uid, ids, name="closed", context=context) + xml_id = self.find_subtype_xml_id(cr, uid, ids, name="closed", context=context) self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True def case_cancel_send_note(self, cr, uid, ids, context=None): for id in ids: msg = _('%s has been cancelled.') % (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - xml_id = self.find_xml_id(cr, uid, ids, name="cancelled", context=context) + xml_id = self.find_subtype_xml_id(cr, uid, ids, name="cancel", context=context) self.message_post(cr, uid, [id], body=msg, subtype_xml_id=xml_id, context=context) return True diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index a1ad9a9c39a..bec5f730fa7 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -8,7 +8,7 @@ - I have add the sub_type name comment with default true - - !record {model: mail.message.subtype, id: mail.mail_subtype_comment }: + !record {model: mail.message.subtype, id: mail.mt_comment }: name: comment res_model: crm.lead - diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index c8eb8829d64..5fe1ee45b1d 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -13,7 +13,7 @@
                    - + comment diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 9ce3a8c8f95..400f3ccaa2d 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -562,8 +562,8 @@ class mail_thread(osv.AbstractModel): "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) - def message_post(self, cr, uid, thread_id, body='', subject=False, - type='notification', parent_id=False, attachments=None, subtype_xml_id='mail_subtype_comment', context=None, **kwargs): + def message_post(self, cr, uid, thread_id, body='', subject=False, type='notification', + subtype_xml_id=None, parent_id=False, attachments=None, context=None, **kwargs): """ Post a new message in an existing thread, returning the new mail.message ID. Extra keyword arguments will be used as default column values for the new mail.message record. diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 2dfb7a75136..1ecdc4b6e5f 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -702,7 +702,7 @@ class test_mail(TestMailMockups): _mail_bodyalt2 = 'Pigs rules\nAdmin\n' filter_subtype_id = self.mail_message_subtype.search(cr, uid, [('default','=',True)]) # Post comment with body and subject, comment preference - msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mail_subtype_comment') + msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mt_comment') notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)]) self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall") From f59a9a83bbd7d75fb885717abe13a475e18fa8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Sep 2012 13:46:12 +0200 Subject: [PATCH 226/726] [CLEAN] sale: cleaned subtypes. bzr revid: tde@openerp.com-20120919114612-6vrcnzl2up2cdqzk --- addons/sale/sale.py | 8 ++++---- addons/sale/sale_data.xml | 18 ++++-------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index cc6e5f71f30..ba85a62ca1d 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1028,7 +1028,7 @@ class sale_order(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Quotation for %s has been created.") % (obj.partner_id.name), subtype_xml_id="sale_subtype_new", context=context) + self.message_post(cr, uid, [obj.id], body=_("Quotation for %s has been created.") % (obj.partner_id.name), subtype_xml_id="mt_sale_new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): @@ -1036,7 +1036,7 @@ class sale_order(osv.osv): def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), subtype_xml_id="sale_subtype_cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), context=context) def delivery_send_note(self, cr, uid, ids, picking_id, context=None): for order in self.browse(cr, uid, ids, context=context): @@ -1048,7 +1048,7 @@ class sale_order(osv.osv): self.message_post(cr, uid, [order.id], body=_("Delivery Order %s scheduled for %s.") % (picking.name, picking_date_str), context=context) def delivery_end_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Order delivered."), subtype_xml_id="sale_subtype_delivered", context=context) + self.message_post(cr, uid, ids, body=_("Order delivered."), subtype_xml_id="mt_sale_delivered", context=context) def invoice_paid_send_note(self, cr, uid, ids, context=None): self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype_xml_id="sale_subtype_paid", context=context) @@ -1056,7 +1056,7 @@ class sale_order(osv.osv): def invoice_send_note(self, cr, uid, ids, invoice_id, context=None): for order in self.browse(cr, uid, ids, context=context): for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id): - self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype_xml_id="sale_subtype_pending", context=context) + self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), context=context) def action_cancel_draft_send_note(self, cr, uid, ids, context=None): return self.message_post(cr, uid, ids, body=_('Sale order set to draft.'), context=context) diff --git a/addons/sale/sale_data.xml b/addons/sale/sale_data.xml index 4337c4bd1e8..3be79035fc6 100644 --- a/addons/sale/sale_data.xml +++ b/addons/sale/sale_data.xml @@ -44,26 +44,16 @@ If you need to manage your sales pipeline (leads, opportunities, phonecalls), you can install the module <i>CRM</i> from the top menu Settings. - - new + + create sale.order - - cancelled - sale.order - - - + paid sale.order - - pending - sale.order - - - + delivered sale.order From 4fa322cfe5334473676b03e8ac6e9ed06eb552b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Sep 2012 13:51:56 +0200 Subject: [PATCH 227/726] [CLEAN] stock: cleaned subtypes. bzr revid: tde@openerp.com-20120919115156-mi80hp8jprnag506 --- addons/stock/stock.py | 16 ++++++---------- addons/stock/stock_data.xml | 22 +++++----------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 77849e12627..f96c3582a6d 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1379,13 +1379,13 @@ class stock_picking(osv.osv): def create_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(obj.type)), subtype_xml_id="stock_in_subtype_new", context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(obj.type)), subtype_xml_id="mt_stock_new", context=context) def scrap_send_note(self, cr, uid, ids, quantity, uom, name, context=None): - return self.message_post(cr, uid, ids, body= _("%s %s %s has been moved to scrap.") % (quantity, uom, name),context=context) + return self.message_post(cr, uid, ids, body=_("%s %s %s has been moved to scrap.") % (quantity, uom, name), context=context) def back_order_send_note(self, cr, uid, ids, back_name, context=None): - return self.message_post(cr, uid, ids, body=_("Back order %s has been created.") % (back_name), subtype_xml_id="stock_in_subtype_new", context=context) + return self.message_post(cr, uid, ids, body=_("Back order %s has been created.") % (back_name), subtype_xml_id="mt_stock_new", context=context) def ship_done_send_note(self, cr, uid, ids, context=None): type_dict = { @@ -1394,19 +1394,15 @@ class stock_picking(osv.osv): 'internal': 'moved', } xml_id_dict = { - 'out':'stock_out_subtype_delivered', - 'in' : 'stock_in_subtype_received' + 'out': 'mt_stock_delivered', + 'in': 'mt_stock_received' } for obj in self.browse(cr, uid, ids, context=context): self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), subtype_xml_id=xml_id_dict.get(obj.type), context=context) def ship_cancel_send_note(self, cr, uid, ids, context=None): - xml_id_dict = { - 'out':'stock_out_subtype_cancelled', - 'in' : 'stock_in_subtype_cancelled' - } for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), subtype_xml_id=xml_id_dict.get(obj.type), context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), context=context) stock_picking() diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index a59642fa912..1ab30af2abc 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -167,30 +167,18 @@ watch your stock valuation, and track production lots upstream and downstream (b - - - new + + + created stock.picking.in - + delivered stock.picking.out - - + received stock.picking.in - - - - cancelled - stock.picking.in - - - cancelled - stock.picking.out From 5e9f78ebfd3b5a996b78fc598417bc68fe33ec9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Sep 2012 14:00:00 +0200 Subject: [PATCH 228/726] [CLEAN] project_issue: cleaned subtypes. bzr revid: tde@openerp.com-20120919120000-62v9f5e24fh3grzd --- addons/project_issue/project_issue.py | 4 +-- addons/project_issue/project_issue_data.xml | 38 +++++++++------------ 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 83eddb83d5e..0677fbfbd75 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -503,7 +503,7 @@ class project_issue(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id="issue_subtype_stage_change", context=context) + return self.message_post(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_xml_id="mt_issue_new", context=context) def case_get_note_msg_prefix(self, cr, uid, id, context=None): """ Override of default prefix for notifications. """ @@ -515,7 +515,7 @@ class project_issue(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): message = _("Project issue created.") - return self.message_post(cr, uid, ids, body=message, subtype_xml_id="issue_subtype_new", context=context) + return self.message_post(cr, uid, ids, body=message, subtype_xml_id="mt_issue_new", context=context) def case_escalate_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): diff --git a/addons/project_issue/project_issue_data.xml b/addons/project_issue/project_issue_data.xml index f6c225a4d00..edd44e52dd2 100644 --- a/addons/project_issue/project_issue_data.xml +++ b/addons/project_issue/project_issue_data.xml @@ -30,27 +30,7 @@ v3.0 - - - - new - project.issue - - - - stage change - project.issue - - - - cancelled - project.issue - - - - closed - project.issue - + mail.group @@ -62,5 +42,21 @@ You can record issues, assign them to a responsible person, and keep track of th Access all issues from the top Project menu, and access the issues of a specific project via the projects gallery view.
                    + + + created + project.issue + + + + stage change + project.issue + + + + closed + project.issue + + From bd998703847e01fdceb565484bbfaf690586d7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 19 Sep 2012 14:03:33 +0200 Subject: [PATCH 229/726] [CLEAN] purchase: cleaned subtypes. bzr revid: tde@openerp.com-20120919120333-sc1vyw0jzfjltin7 --- addons/purchase/purchase.py | 12 ++++++------ addons/purchase/purchase_data.xml | 18 ++++-------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 8bcd6d39ef9..9fe05da33fc 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -741,7 +741,7 @@ class purchase_order(osv.osv): return [('state', '=', 'draft')] def create_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Request for quotation created."), subtype_xml_id="purchase_subtype_new", context=context) + return self.message_post(cr, uid, ids, body=_("Request for quotation created."), subtype_xml_id="mt_purchase_new", context=context) def confirm_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): @@ -759,20 +759,20 @@ class purchase_order(osv.osv): def invoice_send_note(self, cr, uid, ids, invoice_id, context=None): for order in self.browse(cr, uid, ids, context=context): for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id): - self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s is waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), subtype_xml_id="purchase_subtype_pending", context=context) + self.message_post(cr, uid, [order.id], body=_("Draft Invoice of %s %s is waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), context=context) def shipment_done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("""Shipment received."""), subtype_xml_id="purchase_subtype_received", context=context) + self.message_post(cr, uid, ids, body=_("""Shipment received."""), subtype_xml_id="mt_purchase_received", context=context) def invoice_done_send_note(self, cr, uid, ids, context=None): - self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype_xml_id="purchase_subtype_paid", context=context) + self.message_post(cr, uid, ids, body=_("Invoice paid."), subtype_xml_id="mt_purchase_paid", context=context) def draft_send_note(self, cr, uid, ids, context=None): - return self.message_post(cr, uid, ids, body=_("Purchase Order has been set to draft."), subtype_xml_id="purchase_subtype_new", context=context) + return self.message_post(cr, uid, ids, body=_("Purchase Order has been set to draft."), subtype_xml_id="mt_purchase_new", context=context) def cancel_send_note(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), subtype_xml_id="purchase_subtype_cancelled", context=context) + self.message_post(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), context=context) purchase_order() diff --git a/addons/purchase/purchase_data.xml b/addons/purchase/purchase_data.xml index aa62e84e19d..25981e2e01a 100644 --- a/addons/purchase/purchase_data.xml +++ b/addons/purchase/purchase_data.xml @@ -49,28 +49,18 @@ You can also manage purchase requisitions, see also the Purchase Settings. - - new + + created purchase.order - + paid purchase.order - - pending - purchase.order - - - + received purchase.order - - cancelled - purchase.order - - From b63923f1c9c7ac874d42cfb0be931cb460596b3e Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Wed, 19 Sep 2012 17:36:00 +0530 Subject: [PATCH 230/726] [IMP] Add images on button. bzr revid: bth@tinyerp.com-20120919120600-iox3j7ww7ni52lv0 --- addons/base_calendar/crm_meeting_view.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index 928f8d94d5c..558dac71142 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -183,17 +183,19 @@ + +
                    +

                    Message types to follow

                    +
                      +
                      -

                        @@ -30,18 +33,14 @@ \ -
                      • +
                      • - - + +
                        - - - -
                      • From b1d05506ebe2eb1c262e5dbec05f7305603320f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 13:49:47 +0200 Subject: [PATCH 249/726] [FIX] mail_thread: fixed message_subscribe, not recognizing void list compared to none; misc fixes of subtype. bzr revid: tde@openerp.com-20120920114947-64643cmduzww5i5c --- addons/mail/mail_thread.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 39a8e011f3c..5ad76a44c4f 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -143,13 +143,15 @@ class mail_thread(osv.AbstractModel): - message_is_follower: is uid in the document followers - message_subtype_data: data about document subtypes: which are available, which are followed if any """ - res = dict((id, dict(message_subtype_data='')) for id in ids) + res = dict((id, dict(message_subtype_data='', message_is_follower=False)) for id in ids) user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] # find current model subtypes, add them to a dictionary subtype_obj = self.pool.get('mail.message.subtype') subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context) - subtype_dict = dict((subtype.name, dict(default=subtype.default, followed=False)) for subtype in subtype_obj.browse(cr, uid, subtype_ids, context=context)) + subtype_dict = dict((subtype.name, dict(default=subtype.default, followed=False, id=subtype.id)) for subtype in subtype_obj.browse(cr, uid, subtype_ids, context=context)) + for id in ids: + res[id]['message_subtype_data'] = subtype_dict.copy() # find the document followers, update the data fol_obj = self.pool.get('mail.followers') @@ -159,11 +161,11 @@ class mail_thread(osv.AbstractModel): ('res_model', '=', self._name), ], context=context) for fol in fol_obj.browse(cr, uid, fol_ids, context=context): - thread_subtype_dict = subtype_dict.copy() + thread_subtype_dict = res[fol.res_id]['message_subtype_data'] res[fol.res_id]['message_is_follower'] = True for subtype in fol.subtype_ids: thread_subtype_dict[subtype.name]['followed'] = True - res[fol.res_id]['message_subtype_data'] = '%s' % thread_subtype_dict + res[fol.res_id]['message_subtype_data'] = thread_subtype_dict return res @@ -663,6 +665,7 @@ class mail_thread(osv.AbstractModel): def message_subscribe_users(self, cr, uid, ids, user_ids=None, subtype_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not provided, subscribe uid instead. """ + print cr, uid, ids, user_ids, subtype_ids, context if not user_ids: user_ids = [uid] partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] @@ -671,15 +674,14 @@ class mail_thread(osv.AbstractModel): def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None): """ Add partners to the records followers. """ self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) - - if not subtype_ids: + # if subtypes are not specified (and not set to a void list), fetch default ones + if subtype_ids is None: subtype_obj = self.pool.get('mail.message.subtype') subtype_ids = subtype_obj.search(cr, uid, [('default', '=', True), '|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context) - + # update the subscriptions fol_obj = self.pool.get('mail.followers') fol_ids = fol_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context) fol_obj.write(cr, uid, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context) - return True def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None): From 2a33b4cb266e1c087998e9b47bb60431cce5ece7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 13:57:46 +0200 Subject: [PATCH 250/726] [FIX] mail: fixed tests. bzr revid: tde@openerp.com-20120920115746-6ospayxyyi6y9c3z --- addons/mail/tests/test_mail.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 28dd3e6fe4f..11bc860fb0f 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -306,11 +306,10 @@ class test_mail(TestMailMockups): # ---------------------------------------- group_pigs.refresh() - subtype_data = eval(group_pigs.message_subtype_data) - self.assertEqual(set(subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect') - self.assertFalse(subtype_data['comment']['followed'], 'Admin should not follow comments in pigs') - self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs') - self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs') + self.assertEqual(set(group_pigs.message_subtype_data.keys()), set(['comment', 'mt_mg_def', 'mt_all_def', 'mt_mg_nodef', 'mt_all_nodef']), 'mail.group available subtypes incorrect') + self.assertFalse(group_pigs.message_subtype_data['comment']['followed'], 'Admin should not follow comments in pigs') + self.assertTrue(group_pigs.message_subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs') + self.assertTrue(group_pigs.message_subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs') def test_20_message_post(self): """ Tests designed for message_post. """ From 1206b8f7a0c8d2de9cd7ae05eefbd1c84433896f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 13:59:00 +0200 Subject: [PATCH 251/726] [IMP] Addons: added message_is_follower and message_subtype_data invisible fields to all views using Chatter and Followers widgets. bzr revid: tde@openerp.com-20120920115900-vvpfhjvw135vhf91 --- addons/account/account_invoice_view.xml | 6 ++++ .../account_voucher/account_voucher_view.xml | 3 ++ .../voucher_payment_receipt_view.xml | 6 ++++ .../voucher_sales_purchase_view.xml | 6 ++++ addons/analytic/analytic_view.xml | 3 ++ addons/base_calendar/crm_meeting_view.xml | 3 ++ addons/crm/crm_lead_view.xml | 6 ++++ addons/crm/crm_phonecall_view.xml | 3 ++ addons/crm_claim/crm_claim_view.xml | 3 ++ addons/crm_helpdesk/crm_helpdesk_view.xml | 3 ++ addons/event/event_view.xml | 6 ++++ addons/hr_expense/hr_expense_view.xml | 3 ++ addons/hr_holidays/hr_holidays_view.xml | 6 ++++ addons/hr_recruitment/hr_recruitment_view.xml | 3 ++ addons/idea/idea_view.xml | 3 ++ addons/mail/mail_group_view.xml | 6 ++++ addons/mail/mail_thread.py | 1 - addons/mail/res_partner_view.xml | 3 ++ addons/mrp/mrp_view.xml | 6 ++++ addons/mrp_operations/mrp_operations_view.xml | 3 ++ addons/mrp_repair/mrp_repair_view.xml | 3 ++ addons/note/note_view.xml | 32 +++++++++++-------- addons/procurement/procurement_view.xml | 3 ++ addons/product/product_view.xml | 3 ++ addons/project/project_view.xml | 6 ++++ addons/project_issue/project_issue_view.xml | 3 ++ addons/purchase/purchase_view.xml | 3 ++ .../purchase_requisition_view.xml | 3 ++ addons/sale/sale_view.xml | 3 ++ addons/stock/stock_view.xml | 6 ++++ 30 files changed, 133 insertions(+), 14 deletions(-) diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index 1c4d83106ca..a24c86c58f4 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -279,6 +279,9 @@
                        + + +
                        @@ -438,6 +441,9 @@
                        + + +
                        diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml index 07647d02fe3..daf1f7a361e 100644 --- a/addons/account_voucher/account_voucher_view.xml +++ b/addons/account_voucher/account_voucher_view.xml @@ -111,6 +111,9 @@
                        + + +
                        diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml index c41ed6d5577..0e7e4dd3fe7 100644 --- a/addons/account_voucher/voucher_payment_receipt_view.xml +++ b/addons/account_voucher/voucher_payment_receipt_view.xml @@ -240,6 +240,9 @@
                        + + +
                        @@ -409,6 +412,9 @@
                        + + +
                        diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml index 5bcecfa268e..2ba0aa6e691 100644 --- a/addons/account_voucher/voucher_sales_purchase_view.xml +++ b/addons/account_voucher/voucher_sales_purchase_view.xml @@ -147,6 +147,9 @@
                        + + +
                        @@ -302,6 +305,9 @@
                        + + +
                        diff --git a/addons/analytic/analytic_view.xml b/addons/analytic/analytic_view.xml index 51f5428002f..1613a3a20b0 100644 --- a/addons/analytic/analytic_view.xml +++ b/addons/analytic/analytic_view.xml @@ -54,6 +54,9 @@
                        + + +
                        diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index b963de68130..88f62c5320a 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -230,6 +230,9 @@
                        + + +
                        diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index f018a355579..4bfa145188c 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -222,6 +222,9 @@
                        + + +
                        @@ -522,6 +525,9 @@
                        + + +
                        diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml index 8c1e1c9ec76..160c3bfe388 100644 --- a/addons/crm/crm_phonecall_view.xml +++ b/addons/crm/crm_phonecall_view.xml @@ -151,6 +151,9 @@
                        + + +
                        diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml index 820fb38e58a..db9a75eca5e 100644 --- a/addons/crm_claim/crm_claim_view.xml +++ b/addons/crm_claim/crm_claim_view.xml @@ -182,6 +182,9 @@
                        + + +
                        diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml index 5399c9880ca..aec2b8c1e4c 100644 --- a/addons/crm_helpdesk/crm_helpdesk_view.xml +++ b/addons/crm_helpdesk/crm_helpdesk_view.xml @@ -100,6 +100,9 @@
                        + + +
                        diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index fd396053d5d..b2502c23b06 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -198,6 +198,9 @@
                        + + +
                        @@ -480,6 +483,9 @@
                        + + +
                        diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index 5389f88b885..e577d196695 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -140,6 +140,9 @@
                        + + +
                        diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml index 5a2e0603b88..8ac67fa1723 100644 --- a/addons/hr_holidays/hr_holidays_view.xml +++ b/addons/hr_holidays/hr_holidays_view.xml @@ -122,6 +122,9 @@
                        + + +
                        @@ -159,6 +162,9 @@
                        + + +
                        diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml index 08e5f31a2d2..e81da63b73c 100644 --- a/addons/hr_recruitment/hr_recruitment_view.xml +++ b/addons/hr_recruitment/hr_recruitment_view.xml @@ -184,6 +184,9 @@
                        + + +
                        diff --git a/addons/idea/idea_view.xml b/addons/idea/idea_view.xml index eab3d03ceea..3861e86bff8 100644 --- a/addons/idea/idea_view.xml +++ b/addons/idea/idea_view.xml @@ -78,6 +78,9 @@
                        + + +
                        diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 31beba80ecc..a805fb3b575 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -16,6 +16,9 @@ + + + @@ -83,6 +86,9 @@
                        + + +
                        diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 5ad76a44c4f..bf50b582323 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -665,7 +665,6 @@ class mail_thread(osv.AbstractModel): def message_subscribe_users(self, cr, uid, ids, user_ids=None, subtype_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not provided, subscribe uid instead. """ - print cr, uid, ids, user_ids, subtype_ids, context if not user_ids: user_ids = [uid] partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] diff --git a/addons/mail/res_partner_view.xml b/addons/mail/res_partner_view.xml index 2a8430926d5..9589b6409a7 100644 --- a/addons/mail/res_partner_view.xml +++ b/addons/mail/res_partner_view.xml @@ -11,6 +11,9 @@
                        + + +
                        diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index d05893cf778..a379ae9b4cb 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -410,6 +410,9 @@
                        + + +
                        @@ -788,6 +791,9 @@
                        + + +
                        diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml index 834f3000472..f069f06fca7 100644 --- a/addons/mrp_operations/mrp_operations_view.xml +++ b/addons/mrp_operations/mrp_operations_view.xml @@ -108,6 +108,9 @@
                        + + +
                        diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml index 55cbe49c75b..9158944f952 100644 --- a/addons/mrp_repair/mrp_repair_view.xml +++ b/addons/mrp_repair/mrp_repair_view.xml @@ -190,6 +190,9 @@
                        + + +
                        diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index 8d943dde44d..4ed2fade43f 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -50,6 +50,7 @@ + @@ -108,19 +109,24 @@ - note.note.form - note.note - -
                        -
                        - - -
                        - - - - - + note.note.form + note.note + +
                        +
                        + + +
                        + +
                        + + + + + +
                        + +
                        diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index bf73b383216..b6138ca78d3 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -104,6 +104,9 @@
                        + + +
                        diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index d04e6f17fe8..05e3d0b2497 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -202,6 +202,9 @@
                        + + +
                        diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index ff8ac943a67..4d7bceb4599 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -154,6 +154,9 @@
                        + + +
                        @@ -482,6 +485,9 @@
                        + + +
                        diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index be7427fe8f4..6d1d0272ab0 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -160,6 +160,9 @@
                        + + +
                        diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 796fd1351a9..9a2bd02f9a2 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -265,6 +265,9 @@
                        + + +
                        diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml index 1fafec92bc7..13ea40df765 100644 --- a/addons/purchase_requisition/purchase_requisition_view.xml +++ b/addons/purchase_requisition/purchase_requisition_view.xml @@ -103,6 +103,9 @@
                        + + +
                        diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 5c2320a7d5c..32d9b03cdff 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -352,6 +352,9 @@
                        + + +
                        diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 83fed186f42..1a8e7c0ff3f 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -918,6 +918,9 @@
                        + + +
                        @@ -1044,6 +1047,9 @@
                        + + +
                        From 6fa56dcba546286157a07771c8c5a35e6648cec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 14:20:24 +0200 Subject: [PATCH 252/726] [IMP] Followers widget: cleaned code, and now more clearly uses message_is_follower and message_subtype_data fields. bzr revid: tde@openerp.com-20120920122024-wf8ilufgrp1vhccd --- addons/mail/static/src/js/mail_followers.js | 41 ++++++++++--------- addons/mail/static/src/xml/mail_followers.xml | 4 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index c048550611b..58c53d5556a 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -55,7 +55,7 @@ openerp_mail_followers = function(session, mail) { .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); }); - this.$el.on('click', 'ul.oe_mail_recthread_subtypes', function () {self.do_update_subscription(); }) + this.$el.on('click', 'ul.oe_mail_subtypes', function () {self.do_update_subscription(); }) this.$el.on('click', 'button.oe_mail_button_invite', function(event) { action = { type: 'ir.actions.act_window', @@ -80,6 +80,18 @@ openerp_mail_followers = function(session, mail) { }); }, + get_or_set: function(field_name, value) { + if (this.view.fields[field_name]) { + if (value !== undefined) { + this.view.fields[field_name].set_value(value); + } + return this.view.fields[field_name].get_value(); + } + else { + return value; + } + }, + set_value: function(value_, message_is_follower_value_, message_subtype_data_value_) { this.reinit(); if (! this.view.datarecord.id || @@ -87,36 +99,25 @@ openerp_mail_followers = function(session, mail) { this.$el.find('div.oe_mail_recthread_aside').hide(); return; } - if (message_subtype_data_value_ === undefined) { - this.message_subtype_data_value_ = this.view.fields.message_subtype_data && this.view.fields.message_subtype_data.get_value() || {}; - } - else { - this.message_subtype_data_value_ = message_subtype_data_value_; - } - if (message_is_follower_value_ === undefined) { - this.message_is_follower_value_ = this.view.fields.message_is_follower && this.view.fields.message_is_follower.get_value() || false; - } - else { - this.message_is_follower_value_ = message_is_follower_value_; - } + this.message_is_follower_value_ = this.get_or_set('message_is_follower', message_is_follower_value_) || false; + this.message_subtype_data_value_ = this.get_or_set('message_subtype_data', message_subtype_data_value_) || {}; return this.fetch_followers(value_ || this.get_value()); }, fetch_followers: function (value_) { - return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers')); + return this.ds_follow.call('read', [value_, ['name']]).pipe(this.proxy('display_followers')); }, /** Display the followers, evaluate is_follower directly */ display_followers: function (records) { var self = this; - this.message_is_follower = _.indexOf(_.flatten(_.pluck(records, 'user_ids')), this.session.uid) != -1; var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty(); this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')'); _(records).each(function (record) { record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id); $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list); }); - if (this.message_is_follower) { + if (this.message_is_follower_value_) { this.$el.find('button.oe_mail_button_follow').hide(); this.$el.find('button.oe_mail_button_unfollow').show(); } @@ -129,9 +130,11 @@ openerp_mail_followers = function(session, mail) { /** Display subtypes: {'name': default, followed} */ display_subtypes: function (records) { - var self = this - // this.$el.find('ul.oe_mail_recthread_subtype').show(); - var subtype_list = this.$el.find('ul.oe_mail_recthread_subtypes').empty(); + if (! this.message_is_follower_value_) { + this.$('div.oe_mail_recthread_subtypes').remove(); + return; + } + var subtype_list = this.$el.find('ul.oe_mail_subtypes').empty(); _(records).each(function (record, record_name) { record.name = record_name; record.followed = record.followed || undefined; diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index b2922753acf..05eb349ea5d 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -10,9 +10,9 @@ -
                        +

                        Message types to follow

                        -
                          +
                            From fda33df8a608fd5063ae45b7f9db73c9e1c65013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 14:39:59 +0200 Subject: [PATCH 253/726] [FIX] Followers widget: fixed bad refreshing when going through various form views. bzr revid: tde@openerp.com-20120920123959-3799cpr57f7ac3u1 --- addons/mail/static/src/js/mail_followers.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 58c53d5556a..1e650ca7125 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -130,11 +130,10 @@ openerp_mail_followers = function(session, mail) { /** Display subtypes: {'name': default, followed} */ display_subtypes: function (records) { + var subtype_list = this.$('ul.oe_mail_subtypes').empty(); if (! this.message_is_follower_value_) { - this.$('div.oe_mail_recthread_subtypes').remove(); return; } - var subtype_list = this.$el.find('ul.oe_mail_subtypes').empty(); _(records).each(function (record, record_name) { record.name = record_name; record.followed = record.followed || undefined; From 62926be708d81935f2f47d92e4c312f2699133c5 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 20 Sep 2012 15:46:18 +0200 Subject: [PATCH 254/726] [WIP] oauth provider bzr revid: fme@openerp.com-20120920134618-ema9qyumuorvozig --- addons/auth_oauth_provider/__init__.py | 25 ++++++++++ addons/auth_oauth_provider/__openerp__.py | 42 ++++++++++++++++ .../controllers/__init__.py | 22 ++++++++ .../auth_oauth_provider/controllers/main.py | 38 ++++++++++++++ .../static/src/css/oauth_provider.css | 14 ++++++ .../static/src/css/oauth_provider.sass | 17 +++++++ .../static/src/js/oauth_provider.js | 50 +++++++++++++++++++ .../static/src/xml/oauth_provider.xml | 13 +++++ 8 files changed, 221 insertions(+) create mode 100644 addons/auth_oauth_provider/__init__.py create mode 100644 addons/auth_oauth_provider/__openerp__.py create mode 100644 addons/auth_oauth_provider/controllers/__init__.py create mode 100644 addons/auth_oauth_provider/controllers/main.py create mode 100644 addons/auth_oauth_provider/static/src/css/oauth_provider.css create mode 100644 addons/auth_oauth_provider/static/src/css/oauth_provider.sass create mode 100644 addons/auth_oauth_provider/static/src/js/oauth_provider.js create mode 100644 addons/auth_oauth_provider/static/src/xml/oauth_provider.xml diff --git a/addons/auth_oauth_provider/__init__.py b/addons/auth_oauth_provider/__init__.py new file mode 100644 index 00000000000..c19b731933c --- /dev/null +++ b/addons/auth_oauth_provider/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2011 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import controllers + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/auth_oauth_provider/__openerp__.py b/addons/auth_oauth_provider/__openerp__.py new file mode 100644 index 00000000000..71a4971c9b8 --- /dev/null +++ b/addons/auth_oauth_provider/__openerp__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2012 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +{ + 'name': 'OAuth Provider', + 'version': '1.0', + 'category': 'Tools', + 'description': """ +Allow an openerp server to provide OAuth service. +================================================= +""", + 'author': 'OpenERP s.a.', + 'maintainer': 'OpenERP s.a.', + 'website': 'http://www.openerp.com', + 'depends': ['base', 'web'], + #'data': ['res_users.xml'], + 'js': ['static/src/js/oauth_provider.js'], + 'css': ['static/src/css/oauth_provider.css'], + 'qweb': ['static/src/xml/oauth_provider.xml'], + 'installable': True, + 'auto_install': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/controllers/__init__.py b/addons/auth_oauth_provider/controllers/__init__.py new file mode 100644 index 00000000000..c5f359681b9 --- /dev/null +++ b/addons/auth_oauth_provider/controllers/__init__.py @@ -0,0 +1,22 @@ +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011 OpenERP SA (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import main + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/controllers/main.py b/addons/auth_oauth_provider/controllers/main.py new file mode 100644 index 00000000000..50eed95b234 --- /dev/null +++ b/addons/auth_oauth_provider/controllers/main.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2012 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +#import oauth.oauth as oauth +try: + import openerp.addons.web.common.http as openerpweb +except ImportError: + import web.common.http as openerpweb # noqa + + +class AuthOAuthProvider(openerpweb.Controller): + _cp_path = '/oauth2' + + @openerpweb.jsonrequest + def get_access_token(self, req, **kw): + return { + 'access_token': 'hefwjkhfejwk' + } + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/static/src/css/oauth_provider.css b/addons/auth_oauth_provider/static/src/css/oauth_provider.css new file mode 100644 index 00000000000..778179b63b4 --- /dev/null +++ b/addons/auth_oauth_provider/static/src/css/oauth_provider.css @@ -0,0 +1,14 @@ +@charset "utf-8"; +.openerp .oe_oauth_provider { + padding: 0 10px; +} +.openerp .oe_oauth_provider .oe_oauth_provider_error span.oe_i { + font-size: 60px; + color: #990000; + float: left; +} +.openerp .oe_oauth_provider .oe_oauth_provider_error ul { + list-style: none; + float: left; + font-weight: bold; +} diff --git a/addons/auth_oauth_provider/static/src/css/oauth_provider.sass b/addons/auth_oauth_provider/static/src/css/oauth_provider.sass new file mode 100644 index 00000000000..7921f4cc055 --- /dev/null +++ b/addons/auth_oauth_provider/static/src/css/oauth_provider.sass @@ -0,0 +1,17 @@ +@charset "utf-8" + + +.openerp .oe_oauth_provider + padding: 0 10px + .oe_oauth_provider_error + span.oe_i + font-size: 60px + color: #900 + float: left + ul + list-style: none + float: left + font-weight: bold + +// au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers > "%:p:r.css" +// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker: diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js new file mode 100644 index 00000000000..9612559d038 --- /dev/null +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -0,0 +1,50 @@ +openerp.auth_oauth_provider = function(instance) { + +var QWeb = instance.web.qweb; +var _t = instance.web._t; + +instance.web.client_actions.add('oauth2_auth', 'instance.auth_oauth_provider.ProviderAction'); +instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ + template: "auth_oauth_provider", + start: function (parent) { + var self = this; + this._super.apply(this, arguments); + var params = $.deparam($.param.querystring()); + if (params.response_type !== 'token') { + this.error(_t("Unsupported 'response_type' parameter")); + } + if (!params.redirect_uri) { + this.error(_t("No 'redirect_uri' parameter given")); + } + // params.client_id TODO + // params.scope TODO + // params.approval_prompt TODO + if (!this._error) { + instance.session.rpc('/oauth2/get_access_token', {}).then(function(r) { + self.redirect(r.access_token); + }).fail(function() { + self.error(_t("An error occured while contacting the OpenERP server.")); + }); + } + }, + redirect: function(access_token) { + var params = $.deparam($.param.querystring()); + var a = document.createElement('a'); + a.href = params.redirect_uri; + var search = (a.search ? '&' : '?') + 'access_token=' + access_token; + if (params.state) { + search += "&state=" + params.state; + } + var redirect = a.protocol + '//' + a.host + a.pathname + search + a.hash; + //window.location = redirect; + console.log("redirect to", redirect); + }, + error: function(msg) { + this._error = true; + var $msg = $('
                          • ').addClass('oe_oauth_provider_error_text').text(msg); + $msg.appendTo(this.$('.oe_oauth_provider_error').show().find('ul')); + return false; + }, +}); + +}; diff --git a/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml b/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml new file mode 100644 index 00000000000..ddf6ff08789 --- /dev/null +++ b/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml @@ -0,0 +1,13 @@ + + From 100c0a60a5e35d8377fd5225a1b77b745d9a9bd3 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 20 Sep 2012 16:00:41 +0200 Subject: [PATCH 255/726] [ADD] Added res_user oauth token field bzr revid: fme@openerp.com-20120920140041-eied4nfw8pjs6ye8 --- addons/auth_oauth_provider/__init__.py | 1 + .../auth_oauth_provider/controllers/main.py | 5 +-- addons/auth_oauth_provider/res_users.py | 33 +++++++++++++++++++ .../static/src/js/oauth_provider.js | 2 +- 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 addons/auth_oauth_provider/res_users.py diff --git a/addons/auth_oauth_provider/__init__.py b/addons/auth_oauth_provider/__init__.py index c19b731933c..a6f4a72100b 100644 --- a/addons/auth_oauth_provider/__init__.py +++ b/addons/auth_oauth_provider/__init__.py @@ -20,6 +20,7 @@ ############################################################################## import controllers +import res_users # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/controllers/main.py b/addons/auth_oauth_provider/controllers/main.py index 50eed95b234..d0ca059aa93 100644 --- a/addons/auth_oauth_provider/controllers/main.py +++ b/addons/auth_oauth_provider/controllers/main.py @@ -30,9 +30,10 @@ class AuthOAuthProvider(openerpweb.Controller): _cp_path = '/oauth2' @openerpweb.jsonrequest - def get_access_token(self, req, **kw): + def get_token(self, req, **kw): + token = req.session.model('res.users').get_oauth_token() return { - 'access_token': 'hefwjkhfejwk' + 'access_token': token, } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/res_users.py b/addons/auth_oauth_provider/res_users.py new file mode 100644 index 00000000000..667ef3f838e --- /dev/null +++ b/addons/auth_oauth_provider/res_users.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2012 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.osv import osv, fields + +class res_users(osv.osv): + _inherit = 'res.users' + + _columns = { + 'last_oauth_token': fields.char('Last OAuth Token', size=64, readonly=True, invisible=True), + } + + def get_oauth_token(self, cr, uid, context=None): + return "TOKENJEFILWJLK" + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js index 9612559d038..f2bd4b21c00 100644 --- a/addons/auth_oauth_provider/static/src/js/oauth_provider.js +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -20,7 +20,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ // params.scope TODO // params.approval_prompt TODO if (!this._error) { - instance.session.rpc('/oauth2/get_access_token', {}).then(function(r) { + instance.session.rpc('/oauth2/get_token', {}).then(function(r) { self.redirect(r.access_token); }).fail(function() { self.error(_t("An error occured while contacting the OpenERP server.")); From 3774f6d54572584b4860c712ad7e15b3d25fb1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 20 Sep 2012 16:46:45 +0200 Subject: [PATCH 256/726] [IMP] [FIX] Chatter: fixed load more, message_read and expandables. Cleaned tests. bzr revid: tde@openerp.com-20120920144645-o92edguwjzws3t3e --- addons/mail/mail_message.py | 31 ++++++----- addons/mail/static/src/css/mail.css | 25 ++++----- addons/mail/static/src/js/mail.js | 86 ++++------------------------- addons/mail/static/src/xml/mail.xml | 19 ++++++- addons/mail/tests/test_mail.py | 22 ++++---- 5 files changed, 68 insertions(+), 115 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 362b027f6d1..dee44d9f8b8 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -208,7 +208,7 @@ class mail_message(osv.Model): if parent_message and current_level < level: base_domain += [('parent_id', '=', parent_message['id'])] elif parent_message: - base_domain += [('id', 'child_of', parent_message['id'])] + base_domain += [('id', 'child_of', parent_message['id']), ('id', '!=', parent_message['id'])] if domain: base_domain += domain extension = { 'type': 'expandable', @@ -219,7 +219,7 @@ class mail_message(osv.Model): } return extension - def message_read_tree_flatten(self, cr, uid, parent_message, messages, domain=[], level=0, current_level=0, context=None, limit=None): + def message_read_tree_flatten(self, cr, uid, parent_message, messages, domain=[], level=0, current_level=0, context=None, limit=None, add_expandable=True): """ Given a tree with several roots of following structure : [ {'id': 1, 'child_ids': [ {'id': 11, 'child_ids': [...] },], @@ -238,33 +238,36 @@ class mail_message(osv.Model): child_ids = msg_dict.pop('child_ids', []) msg_dict['child_ids'] = [] return [msg_dict] + child_ids + context = context or {} limit = limit or self._message_read_limit + # Depth-first flattening for message in messages: if message.get('type') == 'expandable': continue - message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], domain, level, current_level + 1, context=context) + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], domain, level, current_level + 1, context=context, limit=limit) for child in message['child_ids']: + if child.get('type') == 'expandable': + continue message['child_nbr'] += child['child_nbr'] # Flatten if above maximum depth if current_level < level: return_list = messages else: return_list = [flat_message for message in messages for flat_message in _flatten(message)] + # Add expandable return_list = sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) - if current_level == 0: - expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) - if len(return_list) >= limit: - print 'we need an expandable here' - print 'expandable', expandable - elif current_level <= level: - expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, [], current_level, level, context=context) - print 'expandable', expandable + if return_list and current_level == 0 and add_expandable: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, domain, current_level, level, context=context) + return_list.append(expandable) + elif return_list and current_level <= level and add_expandable: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, domain, current_level, level, context=context) + return_list.append(expandable) return return_list - def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, limit=None, parent_id=False): + def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, parent_id=False, limit=None): """ Read messages from mail.message, and get back a structured tree of messages to be displayed as discussion threads. If IDs is set, fetch these records. Otherwise use the domain to fetch messages. @@ -278,11 +281,11 @@ class mail_message(osv.Model): further parents :return list: list of trees of messages """ - limit = limit or self._message_read_limit context = context or {} if not ids: ids = self.search(cr, uid, domain, context=context, limit=limit) messages = self.browse(cr, uid, ids, context=context) + add_expandable = (len(messages) >= limit) # key: ID, value: record tree = {} @@ -305,7 +308,7 @@ class mail_message(osv.Model): tree[msg.id] = record # Flatten the result - result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context) + result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context, limit=limit, add_expandable=add_expandable) return result #------------------------------------------------------ diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 2f9b35f1c95..8e4185b17f9 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -55,16 +55,6 @@ height: 28px; } -.openerp div.oe_mail_msg_content { - position: relative; - width: 486px; -} - -.openerp div.oe_mail_msg_content > li { - float: left; - margin-right: 3px; -} - .openerp div.oe_mail_thread_subthread div.oe_mail_msg_content { width: 440px; } @@ -196,14 +186,16 @@ margin: 0 0 4px 0; } -.openerp .oe_mail_msg_notification, -.openerp .oe_mail_msg_comment, +.openerp .oe_mail_msg_notification, +.openerp .oe_mail_msg_expandable, +.openerp .oe_mail_msg_comment, .openerp .oe_mail_msg_email { padding: 8px; background: white; border-top: 1px solid #ccc; } +.openerp div.oe_mail_thread_subthread .oe_mail_msg_expandable, .openerp div.oe_mail_thread_subthread .oe_mail_msg_comment { background: #eee; } @@ -216,8 +208,15 @@ clear: both; } -.openerp .oe_mail_msg_content { +.openerp div.oe_mail_msg_content { + float: right; + position: relative; + width: 486px; +} + +.openerp div.oe_mail_msg_content > li { float: left; + margin-right: 3px; } .openerp .oe_mail_msg_content:after { diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 3ab566d2e21..eb25084f530 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -32,27 +32,6 @@ openerp.mail = function(session) { }); - /** - * ------------------------------------------------------------ - * Sidebar - * ------------------------------------------------------------ - * - * Override of sidebar do_attachment_new method, to catch attachments added - * through the sidebar and show them in the Chatter composition form. - */ - - // session.web.Sidebar = session.web.Sidebar.extend({ - // do_attachment_new: function(attachment) { - // this._super(attachment); - // var message_ids = this.getParent().fields.message_ids || undefined; - // if (! message_ids) { return; } - // var compose_message_widget = message_ids.thread.compose_message_widget; - // if (! compose_message_widget) { return; } - // compose_message_widget.attachments.push(attachment); - // compose_message_widget.display_attachments(); - // }, - // }); - /** * ------------------------------------------------------------ * ChatterUtils @@ -308,7 +287,6 @@ openerp.mail = function(session) { show_dd_reply_by_email:options.show_dd_reply_by_email != undefined ? options.show_dd_reply_by_email: true, show_dd_delete: options.show_dd_delete || false, show_dd_hide: options.show_dd_hide || false, - show_more: options.show_more || false, truncate_limit: options.truncate_limit || 250, } // datasets and internal vars @@ -346,7 +324,7 @@ openerp.mail = function(session) { bind_events: function() { var self = this; // event: click on 'More' at bottom of thread - this.$el.on('click', 'button.oe_mail_button_more', this.do_message_fetch_more); + this.$el.on('click', 'a.oe_mail_fetch_more', this.do_message_fetch_more); // event: writing in basic textarea of composition form (quick reply) this.$el.find('textarea.oe_mail_compose_textarea').keyup(function (event) { var charCode = (event.which) ? event.which : window.event.keyCode; @@ -421,7 +399,6 @@ openerp.mail = function(session) { 'default_parent_id': this.context.default_parent_id, 'default_content_subtype': 'plain'} ); } - // return this._super(action, on_close); }, /** Instantiate the composition form, with every parameters in context @@ -459,14 +436,14 @@ openerp.mail = function(session) { message_fetch: function (initial_mode, additional_domain, additional_context) { var self = this; // domain and context: options + additional - fetch_domain = _.flatten([this.domain, additional_domain || []], true) - fetch_context = _.extend(this.context, additional_context || {}) + fetch_domain = _.flatten([this.domain, additional_domain || []], true); + fetch_context = _.extend({}, this.context, additional_context || {}); // initial mode: try to use message_data or message_ids if (initial_mode && this.options.message_data) { return this.message_display(this.options.message_data); } message_ids = initial_mode && this.options.message_ids != null && this.options.message_ids || false; - return this.ds_message.call('message_read', [message_ids, fetch_domain, this.options.thread_level, fetch_context] + return this.ds_message.call('message_read', [message_ids, fetch_domain, this.options.thread_level, fetch_context, this.context.default_parent_id || undefined] ).then(this.proxy('message_display')); }, @@ -476,13 +453,12 @@ openerp.mail = function(session) { */ message_display: function (records) { var self = this; - var _expendable = false; _(records).each(function (record) { if (record.type == 'expandable') { - _expendable = true; - self.update_fetch_more(true); self.fetch_more_domain = record.domain; self.fetch_more_context = record.context; + var rendered = session.web.qweb.render('mail.thread.message.expandable', {'record': record}); + $(rendered).appendTo(self.$el.children('div.oe_mail_thread_display:first')); } else { self.display_record(record); @@ -501,9 +477,6 @@ openerp.mail = function(session) { self.thread.appendTo(self.$el.find('div.oe_mail_thread_subthread:last')); } }); - if (! _expendable) { - this.update_fetch_more(false); - } }, /** Displays a record and performs some formatting on the record : @@ -558,15 +531,6 @@ openerp.mail = function(session) { vote_node.html(vote_element); }, - /** Display 'show more' button */ - update_fetch_more: function (new_value) { - if (new_value) { - this.$el.find('div.oe_mail_thread_more:last').show(); - } else { - this.$el.find('div.oe_mail_thread_more:last').hide(); - } - }, - display_user_avatar: function () { var avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); return this.$el.find('img.oe_mail_icon').attr('src', avatar); @@ -581,45 +545,15 @@ openerp.mail = function(session) { } return this.ds_thread.call('message_post', [ [this.context.default_res_id], body, false, 'comment', this.context.default_parent_id, undefined] - ).then(self.message_fetch()); + ).pipe(self.message_clean()).pipe(self.message_fetch(false)); }, /** Action: 'shows more' to fetch new messages */ - do_message_fetch_more: function () { + do_message_fetch_more: function (event) { + event.stopPropagation(); + $(event.srcElement).parents('li').eq(0).remove(); return this.message_fetch(false, this.fetch_more_domain, this.fetch_more_context); }, - - // TDE: keep currently because need something similar - // /** - // * Create a domain to fetch new comments according to - // * comment already present in comments_structure - // * @param {Object} comments_structure (see chatter utils) - // * @returns {Array} fetch_domain (OpenERP domain style) - // */ - // get_fetch_domain: function (comments_structure) { - // var domain = []; - // var ids = comments_structure.root_ids.slice(); - // var ids2 = []; - // // must be child of current parent - // if (this.options.parent_id) { domain.push(['id', 'child_of', this.options.parent_id]); } - // _(comments_structure.root_ids).each(function (id) { // each record - // ids.push(id); - // ids2.push(id); - // }); - // if (this.options.parent_id != false) { - // ids2.push(this.options.parent_id); - // } - // // must not be children of already fetched messages - // if (ids.length > 0) { - // domain.push('&'); - // domain.push('!'); - // domain.push(['id', 'child_of', ids]); - // } - // if (ids2.length > 0) { - // domain.push(['id', 'not in', ids2]); - // } - // return domain; - // }, }); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index e3586e723e4..cddccedbf6a 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -101,9 +101,9 @@
                            -
                            + @@ -161,6 +161,21 @@
                          • + +
                          • +
                            +
                            + + +
                            +
                          • + - -
                            @@ -441,11 +437,7 @@
                            - - - -
                            diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml index f06960ba7d2..5e26c366778 100644 --- a/addons/account_voucher/account_voucher_view.xml +++ b/addons/account_voucher/account_voucher_view.xml @@ -108,11 +108,7 @@
                            - - - -
                            diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml index 03dc6b33fa2..c41ed6d5577 100644 --- a/addons/account_voucher/voucher_payment_receipt_view.xml +++ b/addons/account_voucher/voucher_payment_receipt_view.xml @@ -239,11 +239,7 @@
                            - - - -
                            @@ -412,11 +408,7 @@
                            - - - -
                            diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml index 2affc51b667..5bcecfa268e 100644 --- a/addons/account_voucher/voucher_sales_purchase_view.xml +++ b/addons/account_voucher/voucher_sales_purchase_view.xml @@ -146,11 +146,7 @@
                            - - - -
                            @@ -305,11 +301,7 @@
                            - - - -
                            diff --git a/addons/analytic/analytic_view.xml b/addons/analytic/analytic_view.xml index 8f25d03ce30..51f5428002f 100644 --- a/addons/analytic/analytic_view.xml +++ b/addons/analytic/analytic_view.xml @@ -53,11 +53,7 @@
                            - - - -
                            diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index 5c0a3790fd6..b963de68130 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -229,11 +229,7 @@
                            - - - -
                            diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 5f52f3e0d93..f91a8756598 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -223,11 +223,7 @@
                            - - - -
                            @@ -529,11 +525,7 @@
                            - - - -
                            diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml index f3ce57f10a9..ea20624d738 100644 --- a/addons/crm/crm_phonecall_view.xml +++ b/addons/crm/crm_phonecall_view.xml @@ -149,11 +149,7 @@
                            - - - -
                            diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml index 38b7e9891cf..820fb38e58a 100644 --- a/addons/crm_claim/crm_claim_view.xml +++ b/addons/crm_claim/crm_claim_view.xml @@ -181,11 +181,7 @@
                            - - - -
                            diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml index d914cd601e8..5399c9880ca 100644 --- a/addons/crm_helpdesk/crm_helpdesk_view.xml +++ b/addons/crm_helpdesk/crm_helpdesk_view.xml @@ -99,11 +99,7 @@
                            - - - -
                            diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index 9f9130ced4d..e7c14aab18f 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -197,11 +197,7 @@
                            - - - -
                            @@ -483,11 +479,7 @@
                            - - - -
                            diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index 265c07328e6..8049255afbf 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -139,11 +139,7 @@
                            - - - -
                            diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml index 84a48e46615..347e2b17ca5 100644 --- a/addons/hr_holidays/hr_holidays_view.xml +++ b/addons/hr_holidays/hr_holidays_view.xml @@ -121,11 +121,7 @@
                            - - - -
                            @@ -162,11 +158,7 @@
                            - - - -
                            diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml index 9e3045d766e..08e5f31a2d2 100644 --- a/addons/hr_recruitment/hr_recruitment_view.xml +++ b/addons/hr_recruitment/hr_recruitment_view.xml @@ -183,11 +183,7 @@
                            - - - -
                            diff --git a/addons/idea/idea_view.xml b/addons/idea/idea_view.xml index 7f42eeb3751..eab3d03ceea 100644 --- a/addons/idea/idea_view.xml +++ b/addons/idea/idea_view.xml @@ -77,11 +77,7 @@
                            - - - -
                            diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 869c76d2110..40f0a754e4f 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -15,12 +15,10 @@ - - - - + +
                            @@ -84,12 +82,8 @@
                            - - - -
                            diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 97e78cfdd15..71d4bfd099b 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -169,6 +169,7 @@ class mail_thread(osv.AbstractModel): for subtype in fol.subtype_ids: thread_subtype_dict[subtype.name]['followed'] = True res[fol.res_id]['message_subtype_data'] = thread_subtype_dict + return res def _search_unread(self, cr, uid, obj=None, name=None, domain=None, context=None): @@ -679,6 +680,11 @@ class mail_thread(osv.AbstractModel): partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] return self.message_subscribe(cr, uid, ids, partner_ids, subtype_ids=subtype_ids, context=context) + def get_message_subtypes(self, cr, uid, ids, context=None): + """ message_subtype_data: data about document subtypes: which are + available, which are followed if any """ + return self._get_subscription_data(cr, uid, ids, None, None, context=context) + def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None): """ Add partners to the records followers. """ self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) diff --git a/addons/mail/res_partner_view.xml b/addons/mail/res_partner_view.xml index 3ef68ac8c59..2a8430926d5 100644 --- a/addons/mail/res_partner_view.xml +++ b/addons/mail/res_partner_view.xml @@ -9,12 +9,8 @@
                            - - - -
                            diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 895aa57bdc5..3fde4cbc67b 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -14,7 +14,6 @@ margin: 0; } - /* ------------------------------------------------------------ */ /* Wall /* ------------------------------------------------------------ */ @@ -37,6 +36,29 @@ list-style-type: none; } +/* ------------------------------------------------------------ */ +/* Followers +/* ------------------------------------------------------------ */ + +.openerp div.oe_mail_recthread_aside h4 { + display: inline-block; +} +.openerp div.oe_mail_recthread_aside button { + position: relative; +} +.openerp div.oe_mail_recthread_aside label, +.openerp div.oe_mail_recthread_aside input { + cursor:pointer; +} +.openerp div.oe_mail_recthread_subtypes { + display:none; +} +.openerp div.oe_mail_recthread_aside button span { + position: absolute; + top:-7px; + right:5px; +} + /* Specific display of threads in the wall */ /* ------------------------------------------------------------ */ @@ -113,15 +135,6 @@ margin-bottom: 8px; } - -/* ------------------------------------------------------------ */ -/* Followers -/* ------------------------------------------------------------ */ - -.openerp div.oe_mail_recthread_aside h4 { - display: inline-block; -} - /* ------------------------------------------------------------ */ /* Thread /* ------------------------------------------------------------ */ diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 0efbf9ca76e..a3ba6f91a04 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -27,9 +27,9 @@ openerp_mail_followers = function(session, mail) { this.options.image = this.node.attrs.image || 'image_small'; this.options.title = this.node.attrs.title || 'Followers'; this.ds_model = new session.web.DataSetSearch(this, this.view.model); - this.sub_model = new session.web.DataSetSearch(this,'mail.message.subtype') + this.sub_model = new session.web.DataSetSearch(this,'mail.message.subtype'); this.ds_follow = new session.web.DataSetSearch(this, this.field.relation); - this.follower_model = new session.web.DataSetSearch(this,'mail.followers') + this.follower_model = new session.web.DataSetSearch(this,'mail.followers'); }, start: function() { @@ -51,11 +51,12 @@ openerp_mail_followers = function(session, mail) { bind_events: function() { var self = this; - this.$el.find('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); }) - .mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); }) - .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); - this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); }); - this.$el.on('click', 'ul.oe_mail_subtypes', function () {self.do_update_subscription(); }) + this.$el.find('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); self.clear_subtypes(); }) + .mouseover(function () { $(this).removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover').find('p').html('Unfollow');}) + .mouseleave(function () { $(this).removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout').find('p').html('Following'); }); + + this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); self.clear_subtypes(); }); + this.$el.on('click', 'ul.oe_mail_subtypes input', function () {self.do_update_subscription(); }) this.$el.on('click', 'button.oe_mail_button_invite', function(event) { action = { type: 'ir.actions.act_window', @@ -71,37 +72,34 @@ openerp_mail_followers = function(session, mail) { } self.do_action(action, function() { self.read_value(); }); }); + + this.$el.find('button span') + .click(function (e) { self.display_subtypes(); e.stopPropagation(); }) }, read_value: function() { var self = this; - return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids', 'message_is_follower', 'message_subtype_data']).pipe(function (results) { - self.set_value(results[0].message_follower_ids, results[0].message_is_follower, results[0].message_subtype_data); + return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) { + self.set_value(results[0].message_follower_ids); }); }, - get_or_set: function(field_name, value) { - if (this.view.fields[field_name]) { - if (value !== undefined) { - this.view.fields[field_name].set_value(value); - } - return this.view.fields[field_name].get_value(); - } - else { - return value; - } + set_value: function(value_) { + console.log("set_value", value_); + this.reinit(); + return this.fetch_followers(value_ || this.get_value()); }, - set_value: function(value_, message_is_follower_value_, message_subtype_data_value_) { - this.reinit(); - if (! this.view.datarecord.id || - session.web.BufferedDataSet.virtual_id_regex.test(this.view.datarecord.id)) { - this.$el.find('div.oe_mail_recthread_aside').hide(); - return; + set_is_follower: function(value_) { + for(var i in value_){ + if(value_[i]['user_ids'][0]==this.session.uid) + this.message_is_follower=true; + this.display_buttons(); + return true; } - this.message_is_follower_value_ = this.get_or_set('message_is_follower', message_is_follower_value_) || false; - this.message_subtype_data_value_ = this.get_or_set('message_subtype_data', message_subtype_data_value_) || {}; - return this.fetch_followers(value_ || this.get_value()); + this.message_is_follower=false; + this.display_buttons(); + return false; }, fetch_followers: function (value_, message_is_follower) { @@ -136,12 +134,11 @@ openerp_mail_followers = function(session, mail) { record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id); $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list); }); - this.display_buttons(); - return this.display_subtypes(this.message_subtype_data_value_); + self.set_is_follower(records); }, display_buttons: function () { - if (this.message_is_follower_value_) { + if (this.message_is_follower) { this.$el.find('button.oe_mail_button_follow').hide(); this.$el.find('button.oe_mail_button_unfollow').show(); } @@ -156,24 +153,48 @@ openerp_mail_followers = function(session, mail) { this.$el.find('span.oe_mail_invite_wrapper').show(); }, - /** Display subtypes: {'name': default, followed} */ - display_subtypes: function (records) { - var subtype_list = this.$el.find('ul.oe_mail_subtypes').empty(); - if (! this.message_is_follower_value_) { - return; - } + set_subtypes:function(data){ + var self = this; + var records = data[this.view.datarecord.id].message_subtype_data; _(records).each(function (record, record_name) { record.name = record_name; record.followed = record.followed || undefined; - $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo(subtype_list); + $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$el.find('ul.oe_mail_subtypes') ); }); }, - + + /** Display subtypes: {'name': default, followed} */ + display_subtypes: function () { + var self = this; + var recthread_subtypes = self.$el.find('.oe_mail_recthread_subtypes'); + subtype_list_ul = self.$el.find('ul.oe_mail_subtypes'); + + if(recthread_subtypes.is(":visible")) { + self.hidden_subtypes(); + } else { + if(subtype_list_ul.is(":empty")) { + var context = new session.web.CompoundContext(this.build_context(), {}); + this.ds_model.call('get_message_subtypes',[[self.view.datarecord.id], context]).pipe(this.proxy('set_subtypes')); + } + + recthread_subtypes.show(); + } + }, + + clear_subtypes: function(){ + this.$el.find('ul.oe_mail_subtypes').empty(); + this.hidden_subtypes(); + }, + + hidden_subtypes: function (){ + this.$el.find('.oe_mail_recthread_subtypes').hide(); + }, + do_follow: function () { var context = new session.web.CompoundContext(this.build_context(), {}); return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, undefined, context]).pipe(this.proxy('read_value')); }, - + do_unfollow: function () { var context = new session.web.CompoundContext(this.build_context(), {}); return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value')); @@ -182,13 +203,15 @@ openerp_mail_followers = function(session, mail) { do_update_subscription: function () { var context = new session.web.CompoundContext(this.build_context(), {}); var self = this; + var checklist = new Array(); _(this.$el.find('.oe_msg_subtype_check')).each(function(record){ if($(record).is(':checked')) { - checklist.push(parseInt($(record).attr('id')))} + checklist.push(parseInt($(record).data('id')))} }); + return this.ds_model.call('message_subscribe_users',[[self.view.datarecord.id], undefined, checklist, context]).pipe(this.proxy('read_value')); }, }); -}; +}; \ No newline at end of file diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index 05eb349ea5d..9d0543bbdca 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -7,9 +7,9 @@ -->
                            - - - + + +

                            Message types to follow

                              @@ -39,8 +39,8 @@
                            • - - + +
                            • diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index b49123b8a38..d05893cf778 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -410,9 +410,6 @@
                              - - -
                              @@ -790,11 +787,7 @@
                              - - - -
                              diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml index 715f0a53531..834f3000472 100644 --- a/addons/mrp_operations/mrp_operations_view.xml +++ b/addons/mrp_operations/mrp_operations_view.xml @@ -107,11 +107,7 @@
                              - - - -
                              diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml index 94a06e6b40d..55cbe49c75b 100644 --- a/addons/mrp_repair/mrp_repair_view.xml +++ b/addons/mrp_repair/mrp_repair_view.xml @@ -189,11 +189,7 @@
                              - - - -
                              diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index 789a112b868..19eff9bc250 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -50,7 +50,6 @@ - @@ -119,9 +118,6 @@
                              - - -
                              diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index 64b10bd2bbf..bf73b383216 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -103,11 +103,7 @@
                              - - - -
                              diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index d175ea391d5..c08bbc412e3 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -203,11 +203,7 @@
                              - - - -
                              diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index fa639f46c6d..93d01a5619b 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -152,11 +152,7 @@
                              - - - -
                              @@ -482,11 +478,7 @@
                              - - - -
                              diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index f9e04e7420e..8d54520261f 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -161,11 +161,7 @@
                              - - - -
                              diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 69042a2fa1a..759c0561631 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -285,11 +285,7 @@
                              - - - -
                              diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml index cba22f384ca..80bdd9aa95b 100644 --- a/addons/purchase_requisition/purchase_requisition_view.xml +++ b/addons/purchase_requisition/purchase_requisition_view.xml @@ -103,9 +103,6 @@
                              - - -
                              diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 54fdcb8c140..5c2320a7d5c 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -351,11 +351,7 @@
                              - - - -
                              diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 2f2dc3a2d8a..83fed186f42 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -917,11 +917,7 @@
                              - - - -
                              @@ -1047,11 +1043,7 @@
                              - - - -
                              From ac7adf29d2e59a9dc31e4c59b0969b448bb5742e Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 24 Sep 2012 12:11:08 +0200 Subject: [PATCH 270/726] [IMP] mail_follower: unfollow when no subtypes following bzr revid: chm@openerp.com-20120924101108-iyhv21w0zkvzb4jb --- addons/mail/static/src/js/mail_followers.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index a3ba6f91a04..85bd4c37987 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -85,7 +85,6 @@ openerp_mail_followers = function(session, mail) { }, set_value: function(value_) { - console.log("set_value", value_); this.reinit(); return this.fetch_followers(value_ || this.get_value()); }, @@ -209,8 +208,11 @@ openerp_mail_followers = function(session, mail) { if($(record).is(':checked')) { checklist.push(parseInt($(record).data('id')))} }); - - return this.ds_model.call('message_subscribe_users',[[self.view.datarecord.id], undefined, checklist, context]).pipe(this.proxy('read_value')); + + if(!checklist.length) + return this.do_unfollow(); + else + return this.ds_model.call('message_subscribe_users',[[self.view.datarecord.id], undefined, checklist, context]).pipe(this.proxy('read_value')); }, }); From b4421c8fba5a7208a0cf38708cfaa235d9bfa497 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 12:14:04 +0200 Subject: [PATCH 271/726] [ADD] cache dict on the cursor, for request-local repeated reads bzr revid: xmo@openerp.com-20120924101404-cel6oy1akabbo7id --- openerp/sql_db.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 7b6f4469b8d..a6ebcd0300f 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -138,6 +138,16 @@ class Cursor(object): sure you use psycopg2 v2.4.2 or newer if you use PostgreSQL 9.1 and the performance hit is a concern for you. + .. attribute:: cache + + Cache dictionary with a "request" (-ish) lifecycle, only lives as + long as the cursor itself does and proactively cleared when the + cursor is closed. + + This cache should *only* be used to store repeatable reads as it + ignores rollbacks and savepoints, it should not be used to store + *any* data which may be modified during the life of the cursor. + """ IN_MAX = 1000 # decent limit on size of IN queries - guideline = Oracle limit @@ -182,6 +192,8 @@ class Cursor(object): self._default_log_exceptions = True + self.cache = {} + def __del__(self): if not self.__closed and not self._cnx.closed: # Oops. 'self' has not been closed explicitly. @@ -279,6 +291,8 @@ class Cursor(object): if not self._obj: return + del self.cache + if self.sql_log: self.__closer = frame_codeinfo(currentframe(),3) self.print_log() From f0a883e6d6b942fc54dea0db0bcb8f3f33170098 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 24 Sep 2012 12:26:13 +0200 Subject: [PATCH 272/726] [FIX] point_of_sale: Show the opening_control & closing_control bzr revid: stw@openerp.com-20120924102613-twii7ba34wctx6c6 --- addons/point_of_sale/point_of_sale_view.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 9c92145ed89..d88e1f73cc2 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -896,8 +896,11 @@ - + + + @@ -917,7 +920,7 @@ -
                              +
                              From 449a86a51f62c2e3379fc649c55d89080c278fa4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 12:32:57 +0200 Subject: [PATCH 273/726] [IMP] cache boolean and selection translations for the request (cursor) to avoid fetching them over and over again bzr revid: xmo@openerp.com-20120924103257-1jgc3qhddzzi5c17 --- openerp/addons/base/ir/ir_fields.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 10b80511c73..73e748015a3 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -95,11 +95,20 @@ class ir_fields_converter(orm.Model): return value or False def _get_translations(self, cr, uid, types, src, context): + types = tuple(types) + # Cache translations so they don't have to be reloaded from scratch on + # every row of the file + tnx_cache = cr.cache.setdefault(self._name, {}) + if tnx_cache.setdefault(types, {}) and src in tnx_cache[types]: + return tnx_cache[types][src] + Translations = self.pool['ir.translation'] tnx_ids = Translations.search( cr, uid, [('type', 'in', types), ('src', '=', src)], context=context) tnx = Translations.read(cr, uid, tnx_ids, ['value'], context=context) - return map(operator.itemgetter('value'), tnx) + result = tnx_cache[types][src] = map(operator.itemgetter('value'), tnx) + return result + def _str_to_selection(self, cr, uid, model, column, value, context=None): selection = column.selection From a74b35ee3758545dabd811fe8ac9d0c68a3420ca Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 24 Sep 2012 12:39:31 +0200 Subject: [PATCH 274/726] [ADD] Added oauth approval wip bzr revid: fme@openerp.com-20120924103931-d2zj6p8shpljf0v9 --- .../static/src/js/oauth_provider.js | 40 ++++++++++++------- .../static/src/xml/oauth_provider.xml | 11 +++++ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js index eb2c1982d31..a5e05c60283 100644 --- a/addons/auth_oauth_provider/static/src/js/oauth_provider.js +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -20,15 +20,22 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ // TODO: check if client_id application is authorized to use the service, and get it's name // that should be displayed in the approval confirmation dialog. - // params.approval_prompt TODO if (!this._error) { - instance.session.rpc('/oauth2/get_token', { - client_id: params.client_id || '', - scope: params.scope || '', - }).then(function(result) { - self.redirect(result); - }).fail(function() { - self.error(_t("An error occured while contacting the OpenERP server.")); + // params.approval_prompt TODO + // TODO: get client_id and scope + this.$('.oe_oauth_provider_approval').show().on('click', '.oe_oauth_provider_allow', function() { + instance.session.rpc('/oauth2/get_token', { + client_id: params.client_id || '', + scope: params.scope || '', + }).then(function(result) { + self.redirect(result); + }).fail(function() { + self.error(_t("An error occured while contacting the OpenERP server.")); + }); + }).on('click', '.oe_oauth_provider_deny', function() { + self.redirect({ + error: 'access_denied' + }); }); } }, @@ -36,16 +43,19 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ var params = $.deparam($.param.querystring()); var a = document.createElement('a'); a.href = params.redirect_uri; - var new_params = { - access_token: result.access_token, - token_type: 'Bearer', - }; + var new_params = {}; + if (!result.error) { + new_params.access_token = result.access_token; + new_params.token_type = 'Bearer'; + if (result.expires_in) { + new_params.expires_in = result.expires_in; + } + } else { + new_params.error = result.error; + } if (params.state) { new_params.state = params.state; } - if (result.expires_in) { - new_params.expires_in = result.expires_in; - } var redirect = a.protocol + '//' + a.host + a.pathname + '?' + $.param(new_params) + a.hash; //window.location = redirect; console.log("redirect to", redirect); diff --git a/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml b/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml index ddf6ff08789..85985e4e974 100644 --- a/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml +++ b/addons/auth_oauth_provider/static/src/xml/oauth_provider.xml @@ -8,6 +8,17 @@ D
                              +
                              From 877e21ffdebeba412b7cb4db5fdf352adfac2ff2 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 12:52:30 +0200 Subject: [PATCH 275/726] [IMP] return fields_get-style translated field strings (if available) in user-readable warning and error messages from import, rather than logical field names bzr revid: xmo@openerp.com-20120924105230-1b7157xbruy2e5zr --- openerp/osv/orm.py | 19 +++++++++++--- .../addons/test_impex/tests/test_load.py | 26 +++++++++---------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 57cc5823dd9..e58d6b76a76 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1585,8 +1585,15 @@ class BaseModel(object): :returns: a list of triplets of (id, xid, record) :rtype: list((int|None, str|None, dict)) """ + if context is None: context = {} Converter = self.pool['ir.fields.converter'] columns = dict((k, v.column) for k, v in self._all_columns.iteritems()) + Translation = self.pool['ir.translation'] + field_names = dict( + (f, (Translation._get_source(cr, uid, self._name + ',' + f, 'field', + context.get('lang', False) or 'en_US') + or column.string or f)) + for f, column in columns.iteritems()) converters = dict( (k, Converter.to_field(cr, uid, self, column, context=context)) for k, column in columns.iteritems()) @@ -1619,18 +1626,24 @@ class BaseModel(object): for field, strvalue in record.iteritems(): if field in (None, 'id', '.id'): continue - message_base = dict(extras, record=stream.index, field=field) + # In warnings and error messages, use translated string as + # field name + message_base = dict( + extras, record=stream.index, field=field_names[field]) with warnings.catch_warnings(record=True) as w: try: converted[field] = converters[field](strvalue) + # In warning and error returned, use logical field name + # as field so client can reverse for warning in w: - log(dict(message_base, type='warning', + log(dict(message_base, type='warning', field=field, message=unicode(warning.message) % message_base)) except ValueError, e: log(dict(message_base, type='error', - message=unicode(e) % message_base + field=field, + message=unicode(e) % message_base, )) yield dbid, xid, converted, dict(extras, record=stream.index) diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index 28957c29555..cf95f5bb6c4 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -186,7 +186,7 @@ class test_boolean_field(ImporterCase): ids, messages = self.import_(['value'], trues) self.assertEqual(len(ids), 10) self.assertEqual(messages, [ - message(u"Unknown value '%s' for boolean field 'value', assuming 'yes'" % v[0], + message(u"Unknown value '%s' for boolean field 'unknown', assuming 'yes'" % v[0], type='warning', from_=i, to_=i, record=i) for i, v in enumerate(trues) if v[0] != 'true' if v[0] != 'yes' if v[0] != '1' @@ -460,7 +460,7 @@ class test_selection(ImporterCase): 'rows': {'from': 0, 'to': 0}, 'record': 0, 'field': 'value', - 'message': "Value 'Baz' not found in selection field 'value'", + 'message': "Value 'Baz' not found in selection field 'unknown'", }]) ids, messages = self.import_(['value'], [[42]]) @@ -470,7 +470,7 @@ class test_selection(ImporterCase): 'rows': {'from': 0, 'to': 0}, 'record': 0, 'field': 'value', - 'message': "Value '42' not found in selection field 'value'", + 'message': "Value '42' not found in selection field 'unknown'", }]) class test_selection_function(ImporterCase): @@ -583,7 +583,7 @@ class test_m2o(ImporterCase): ids, messages = self.import_(['value'], [[name2]]) self.assertEqual( messages, - [message(u"Found multiple matches for field 'value' (2 matches)", + [message(u"Found multiple matches for field 'unknown' (2 matches)", type='warning')]) self.assertEqual(len(ids), 1) self.assertEqual([ @@ -607,7 +607,7 @@ class test_m2o(ImporterCase): [integer_id1], ]) self.assertEqual(messages, [ - message(u"No matching record found for name '%s' in field 'value'" % id, + message(u"No matching record found for name '%s' in field 'unknown'" % id, from_=index, to_=index, record=index) for index, id in enumerate([integer_id1, integer_id2, integer_id1])]) self.assertIs(ids, False) @@ -626,19 +626,19 @@ class test_m2o(ImporterCase): ids, messages = self.import_(['value'], [['nameisnoexist:3']]) self.assertEqual(messages, [message( u"No matching record found for name 'nameisnoexist:3' " - u"in field 'value'")]) + u"in field 'unknown'")]) self.assertIs(ids, False) ids, messages = self.import_(['value/id'], [['noxidhere']]) self.assertEqual(messages, [message( u"No matching record found for external id 'noxidhere' " - u"in field 'value'")]) + u"in field 'unknown'")]) self.assertIs(ids, False) ids, messages = self.import_(['value/.id'], [['66']]) self.assertEqual(messages, [message( u"No matching record found for database id '66' " - u"in field 'value'")]) + u"in field 'unknown'")]) self.assertIs(ids, False) def test_fail_multiple(self): @@ -646,7 +646,7 @@ class test_m2o(ImporterCase): ['value', 'value/id'], [['somename', 'somexid']]) self.assertEqual(messages, [message( - u"Ambiguous specification for field 'value', only provide one of " + u"Ambiguous specification for field 'unknown', only provide one of " u"name, external id or database id")]) self.assertIs(ids, False) @@ -690,7 +690,7 @@ class test_m2m(ImporterCase): ids, messages = self.import_(['value/.id'], [['42']]) self.assertEqual(messages, [message( u"No matching record found for database id '42' in field " - u"'value'")]) + u"'unknown'")]) self.assertIs(ids, False) def test_xids(self): @@ -716,7 +716,7 @@ class test_m2m(ImporterCase): ids, messages = self.import_(['value/id'], [['noxidforthat']]) self.assertEqual(messages, [message( u"No matching record found for external id 'noxidforthat' " - u"in field 'value'")]) + u"in field 'unknown'")]) self.assertIs(ids, False) def test_names(self): @@ -745,7 +745,7 @@ class test_m2m(ImporterCase): ids, messages = self.import_(['value'], [['wherethem2mhavenonames']]) self.assertEqual(messages, [message( u"No matching record found for name 'wherethem2mhavenonames' in " - u"field 'value'")]) + u"field 'unknown'")]) self.assertIs(ids, False) def test_import_to_existing(self): @@ -778,7 +778,7 @@ class test_o2m(ImporterCase): ['const', 'value'], [['5', s]]) self.assertEqual(messages, [message( - u"No matching record found for name '%s' in field 'value'" % s)]) + u"No matching record found for name '%s' in field 'unknown'" % s)]) self.assertIs(ids, False) def test_single(self): From 24a4e57171fd0ce371260370226f4c90607f390b Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 24 Sep 2012 13:53:20 +0200 Subject: [PATCH 276/726] [FIX] point_of_sale: show the opening cash control bzr revid: stw@openerp.com-20120924115320-nkbfhfnyab4bhxrc --- addons/point_of_sale/point_of_sale_view.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index d88e1f73cc2..131909a1fd3 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -896,11 +896,7 @@
                              - - - + From a9c2cfcdb91c79cc60de909a4e23bd9e9e5f9787 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 16:57:50 +0200 Subject: [PATCH 277/726] [IMP] make help attribute available on all actions bzr revid: xmo@openerp.com-20120924145750-n0gj4bww1d83h3fy --- openerp/addons/base/ir/ir_actions.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 383f78181e9..b14f4cd7e84 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -19,14 +19,11 @@ # ############################################################################## -import ast -import copy import logging import os import re import time import tools -from xml import dom import netsvc from osv import fields,osv @@ -47,6 +44,9 @@ class actions(osv.osv): 'name': fields.char('Name', size=64, required=True), 'type': fields.char('Action Type', required=True, size=32,readonly=True), 'usage': fields.char('Action Usage', size=32), + 'help': fields.text('Action description', + help='Optional help text for the users with a description of the target view, such as its usage and purpose.', + translate=True), } _defaults = { 'usage': lambda *a: False, @@ -107,6 +107,7 @@ class report_xml(osv.osv): r['report_xsl'] and opj('addons',r['report_xsl'])) _name = 'ir.actions.report.xml' + _inherit = 'ir.actions.actions' _table = 'ir_act_report_xml' _sequence = 'ir_actions_id_seq' _order = 'name' @@ -155,6 +156,7 @@ report_xml() class act_window(osv.osv): _name = 'ir.actions.act_window' _table = 'ir_act_window' + _inherit = 'ir.actions.actions' _sequence = 'ir_actions_id_seq' _order = 'name' @@ -245,9 +247,6 @@ class act_window(osv.osv): 'filter': fields.boolean('Filter'), 'auto_search':fields.boolean('Auto Search'), 'search_view' : fields.function(_search_view, type='text', string='Search View'), - 'help': fields.text('Action description', - help='Optional help text for the users with a description of the target view, such as its usage and purpose.', - translate=True), 'multi': fields.boolean('Action on Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view"), } @@ -331,6 +330,7 @@ act_wizard() class act_url(osv.osv): _name = 'ir.actions.url' _table = 'ir_act_url' + _inherit = 'ir.actions.actions' _sequence = 'ir_actions_id_seq' _order = 'name' _columns = { @@ -432,6 +432,7 @@ class actions_server(osv.osv): _name = 'ir.actions.server' _table = 'ir_act_server' + _inherit = 'ir.actions.actions' _sequence = 'ir_actions_id_seq' _order = 'sequence,name' _columns = { From f143902d1afa345c8fad935a80a6b404a9a3cfb7 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 17:04:17 +0200 Subject: [PATCH 278/726] [IMP] allow converters to add data to import messages, formalize message keys bzr revid: xmo@openerp.com-20120924150417-c2y7g7vdsfz66363 --- openerp/addons/base/ir/ir_fields.py | 33 +++++++-- openerp/osv/orm.py | 70 +++++++++++++++---- .../addons/test_impex/tests/test_load.py | 32 +++------ 3 files changed, 94 insertions(+), 41 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 73e748015a3..2256542533b 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -38,6 +38,26 @@ class ir_fields_converter(orm.Model): By default, tries to get a method on itself with a name matching the pattern ``_$fromtype_$column._type`` and returns it. + Converter callables can either return a value to their caller or raise + ``ValueError``, which will be interpreted as a validation & conversion + failure. + + ValueError can have either one or two parameters. The first parameter + is mandatory, **must** be a unicode string and will be used as the + user-visible message for the error (it should be translatable and + translated). It can contain a ``field`` named format placeholder so the + caller can inject the field's translated, user-facing name (@string). + + The second parameter is optional and, if provided, must be a mapping. + This mapping will be merged into the error dictionary returned to the + client. + + If a converter can perform its function but has to make assumptions + about the data, it can send a warning to the user through signalling + an :class:`~openerp.osv.orm.ImportWarning` (via ``warnings.warn``). The + handling of a warning at the upper levels is the same as + ``ValueError`` above. + :param cr: openerp cursor :param uid: ID of user calling the converter :param column: column object to generate a value for @@ -74,10 +94,9 @@ class ir_fields_converter(orm.Model): )) if value.lower() in falses: return False - warnings.warn( + warnings.warn(orm.ImportWarning( _(u"Unknown value '%s' for boolean field '%%(field)s', assuming '%s'") - % (value, yes), - orm.ImportWarning) + % (value, yes))) return True def _str_to_integer(self, cr, uid, model, column, value, context=None): @@ -124,7 +143,9 @@ class ir_fields_converter(orm.Model): return item raise ValueError( _(u"Value '%s' not found in selection field '%%(field)s'") % ( - value)) + value), { + 'moreinfo': map(operator.itemgetter(1), selection) + }) def db_id_for(self, cr, uid, model, column, subfield, value, context=None): @@ -174,9 +195,9 @@ class ir_fields_converter(orm.Model): cr, uid, name=value, operator='=', context=context) if ids: if len(ids) > 1: - warnings.warn( + warnings.warn(orm.ImportWarning( _(u"Found multiple matches for field '%%(field)s' (%d matches)") - % (len(ids)), orm.ImportWarning) + % (len(ids)))) id, _name = ids[0] else: raise Exception(u"Unknown sub-field '%s'" % subfield) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index e58d6b76a76..98e24075311 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1444,6 +1444,40 @@ class BaseModel(object): def load(self, cr, uid, fields, data, context=None): """ + Attempts to load the data matrix, and returns a list of ids (or + ``False`` if there was an error and no id could be generated) and a + list of messages. + + Each message is a dictionary with the following keys: + + ``type`` + the type of message, either ``warning`` or ``error``. Any ``error`` + message indicates the import failed and was rolled back. + ``message`` + the message's actual text, which should be translated and can be + shown to the user directly + ``rows`` + a dict with 2 keys ``from`` and ``to``, indicates the range of rows + in ``data`` which generated the message + ``record`` + a single integer, for warnings the index of the record which + generated the message (can be obtained from a non-false ``ids`` + result) + ``field`` + the name of the (logical) OpenERP field for which the error or + warning was generated + ``moreinfo`` (optional) + A string, a list or a dict, leading to more information about the + warning. + + * If ``moreinfo`` is a string, it is a supplementary warnings + message which should be hidden by default + * If ``moreinfo`` is a list, it provides a number of possible or + alternative values for the string + * If ``moreinfo`` is a dict, it is an OpenERP action descriptor + which can be executed to get more information about the issues + with the field. If present, the ``help`` key serves as a label + for the action (e.g. the text of the link). :param cr: cursor for the request :param int uid: ID of the user attempting the data import @@ -1598,6 +1632,14 @@ class BaseModel(object): (k, Converter.to_field(cr, uid, self, column, context=context)) for k, column in columns.iteritems()) + def _log(base, field, exception): + type = 'warning' if isinstance(exception, Warning) else 'error' + record = dict(base, field=field, type=type, + message=unicode(exception.args[0]) % base) + if len(exception.args) > 1 and exception.args[1]: + record.update(exception.args[1]) + log(record) + stream = CountingStream(records) for record, extras in stream: dbid = False @@ -1630,21 +1672,23 @@ class BaseModel(object): # field name message_base = dict( extras, record=stream.index, field=field_names[field]) - with warnings.catch_warnings(record=True) as w: - try: + try: + with warnings.catch_warnings(record=True) as ws: converted[field] = converters[field](strvalue) - # In warning and error returned, use logical field name - # as field so client can reverse - for warning in w: - log(dict(message_base, type='warning', field=field, - message=unicode(warning.message) % message_base)) - except ValueError, e: - log(dict(message_base, - type='error', - field=field, - message=unicode(e) % message_base, - )) + for warning in ws: + # bubble non-import warnings upward + if warning.category != ImportWarning: + warnings.warn(warning.message, warning.category) + continue + w = warning.message + if isinstance(w, basestring): + # wrap warning string in an ImportWarning for + # uniform handling + w = ImportWarning(w) + _log(message_base, field, w) + except ValueError, e: + _log(message_base, field, e) yield dbid, xid, converted, dict(extras, record=stream.index) diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index cf95f5bb6c4..f97dafaaf39 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -5,14 +5,10 @@ import openerp from openerp.tests import common from openerp.tools.misc import mute_logger -def message(msg, type='error', from_=0, to_=0, record=0, field='value'): - return { - 'type': type, - 'rows': {'from': from_, 'to': to_}, - 'record': record, - 'field': field, - 'message': msg - } +def message(msg, type='error', from_=0, to_=0, record=0, field='value', **kwargs): + return dict(kwargs, + type=type, rows={'from': from_, 'to': to_}, record=record, + field=field, message=msg) def error(row, message, record=None, **kwargs): """ Failed import of the record ``record`` at line ``row``, with the error @@ -455,23 +451,15 @@ class test_selection(ImporterCase): def test_invalid(self): ids, messages = self.import_(['value'], [['Baz']]) self.assertIs(ids, False) - self.assertEqual(messages, [{ - 'type': 'error', - 'rows': {'from': 0, 'to': 0}, - 'record': 0, - 'field': 'value', - 'message': "Value 'Baz' not found in selection field 'unknown'", - }]) + self.assertEqual(messages, [message( + u"Value 'Baz' not found in selection field 'unknown'", + moreinfo="Foo Bar Qux".split())]) ids, messages = self.import_(['value'], [[42]]) self.assertIs(ids, False) - self.assertEqual(messages, [{ - 'type': 'error', - 'rows': {'from': 0, 'to': 0}, - 'record': 0, - 'field': 'value', - 'message': "Value '42' not found in selection field 'unknown'", - }]) + self.assertEqual(messages, [message( + u"Value '42' not found in selection field 'unknown'", + moreinfo="Foo Bar Qux".split())]) class test_selection_function(ImporterCase): model_name = 'export.selection.function' From 9f2e7ba7ef86808ea5f10af178e7aeb939426323 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Sep 2012 17:15:02 +0200 Subject: [PATCH 279/726] [IMP] return a dict from Model.load for easier future extensibility (if needed) rather than a tuple. also easier/cleaner to unpack on the JS side bzr revid: xmo@openerp.com-20120924151502-4robe639ctpuvb94 --- openerp/osv/orm.py | 6 +- .../addons/test_impex/tests/test_load.py | 378 +++++++++--------- 2 files changed, 192 insertions(+), 192 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 98e24075311..b824be91b96 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1486,7 +1486,7 @@ class BaseModel(object): :param data: row-major matrix of data to import :type data: list(list(str)) :param dict context: - :returns: + :returns: {ids: list(int)|False, messages: [Message]} """ cr.execute('SAVEPOINT model_load') messages = [] @@ -1516,8 +1516,8 @@ class BaseModel(object): messages.append(dict(info, type="error", message=str(e))) if any(message['type'] == 'error' for message in messages): cr.execute('ROLLBACK TO SAVEPOINT model_load') - return False, messages - return ids, messages + ids = False + return {'ids': ids, 'messages': messages} def _extract_records(self, cr, uid, fields_, data, context=None, log=lambda a: None): """ Generates record dicts from the data iterable. diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index f97dafaaf39..060b32c48f5 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -100,9 +100,9 @@ class test_ids_stuff(ImporterCase): model_name = 'export.integer' def test_create_with_id(self): - ids, messages = self.import_(['.id', 'value'], [['42', '36']]) - self.assertIs(ids, False) - self.assertEqual(messages, [{ + result = self.import_(['.id', 'value'], [['42', '36']]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [{ 'type': 'error', 'rows': {'from': 0, 'to': 0}, 'record': 0, @@ -110,9 +110,9 @@ class test_ids_stuff(ImporterCase): 'message': u"Unknown database identifier '42'", }]) def test_create_with_xid(self): - ids, messages = self.import_(['id', 'value'], [['somexmlid', '42']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['id', 'value'], [['somexmlid', '42']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual( 'somexmlid', self.xid(self.browse()[0])) @@ -123,9 +123,9 @@ class test_ids_stuff(ImporterCase): 36, self.model.browse(self.cr, openerp.SUPERUSER_ID, id).value) - ids, messages = self.import_(['.id', 'value'], [[str(id), '42']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['.id', 'value'], [[str(id), '42']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual( [42], # updated value to imported values(self.read())) @@ -143,12 +143,12 @@ class test_boolean_field(ImporterCase): def test_empty(self): self.assertEqual( self.import_(['value'], []), - ([], [])) + {'ids': [], 'messages': []}) def test_exported(self): - ids, messages = self.import_(['value'], [['False'], ['True'], ]) - self.assertEqual(len(ids), 2) - self.assertFalse(messages) + result = self.import_(['value'], [['False'], ['True'], ]) + self.assertEqual(len(result['ids']), 2) + self.assertFalse(result['messages']) records = self.read() self.assertEqual([ False, @@ -170,18 +170,18 @@ class test_boolean_field(ImporterCase): [u'klaidingas'], # false, lt, ] - ids, messages = self.import_(['value'], falses) - self.assertFalse(messages) - self.assertEqual(len(ids), len(falses)) + result = self.import_(['value'], falses) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), len(falses)) self.assertEqual([False] * len(falses), values(self.read())) def test_trues(self): trues = [['None'], ['nil'], ['()'], ['f'], ['#f'], # Problem: OpenOffice (and probably excel) output localized booleans ['VRAI'], ['ok'], ['true'], ['yes'], ['1'], ] - ids, messages = self.import_(['value'], trues) - self.assertEqual(len(ids), 10) - self.assertEqual(messages, [ + result = self.import_(['value'], trues) + self.assertEqual(len(result['ids']), 10) + self.assertEqual(result['messages'], [ message(u"Unknown value '%s' for boolean field 'unknown', assuming 'yes'" % v[0], type='warning', from_=i, to_=i, record=i) for i, v in enumerate(trues) @@ -197,69 +197,69 @@ class test_integer_field(ImporterCase): def test_none(self): self.assertEqual( self.import_(['value'], []), - ([], [])) + {'ids': [], 'messages': []}) def test_empty(self): - ids, messages = self.import_(['value'], [['']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual( [False], values(self.read())) def test_zero(self): - ids, messages = self.import_(['value'], [['0']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['0']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) - ids, messages = self.import_(['value'], [['-0']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['-0']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual([False, False], values(self.read())) def test_positives(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['1'], ['42'], [str(2**31-1)], ['12345678'] ]) - self.assertEqual(len(ids), 4) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 4) + self.assertFalse(result['messages']) self.assertEqual([ 1, 42, 2**31-1, 12345678 ], values(self.read())) def test_negatives(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['-1'], ['-42'], [str(-(2**31 - 1))], [str(-(2**31))], ['-12345678'] ]) - self.assertEqual(len(ids), 5) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 5) + self.assertFalse(result['messages']) self.assertEqual([ -1, -42, -(2**31 - 1), -(2**31), -12345678 ], values(self.read())) @mute_logger('openerp.sql_db') def test_out_of_range(self): - ids, messages = self.import_(['value'], [[str(2**31)]]) - self.assertIs(ids, False) - self.assertEqual(messages, [{ + result = self.import_(['value'], [[str(2**31)]]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [{ 'type': 'error', 'rows': {'from': 0, 'to': 0}, 'record': 0, 'message': "integer out of range\n" }]) - ids, messages = self.import_(['value'], [[str(-2**32)]]) - self.assertIs(ids, False) - self.assertEqual(messages, [{ + result = self.import_(['value'], [[str(-2**32)]]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [{ 'type': 'error', 'rows': {'from': 0, 'to': 0}, 'record': 0, @@ -267,9 +267,9 @@ class test_integer_field(ImporterCase): }]) def test_nonsense(self): - ids, messages = self.import_(['value'], [['zorglub']]) - self.assertIs(ids, False) - self.assertEqual(messages, [{ + result = self.import_(['value'], [['zorglub']]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [{ 'type': 'error', 'rows': {'from': 0, 'to': 0}, 'record': 0, @@ -282,29 +282,29 @@ class test_float_field(ImporterCase): def test_none(self): self.assertEqual( self.import_(['value'], []), - ([], [])) + {'ids': [], 'messages': []}) def test_empty(self): - ids, messages = self.import_(['value'], [['']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual( [False], values(self.read())) def test_zero(self): - ids, messages = self.import_(['value'], [['0']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['0']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) - ids, messages = self.import_(['value'], [['-0']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['-0']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual([False, False], values(self.read())) def test_positives(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['1'], ['42'], [str(2**31-1)], @@ -312,15 +312,15 @@ class test_float_field(ImporterCase): [str(2**33)], ['0.000001'], ]) - self.assertEqual(len(ids), 6) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 6) + self.assertFalse(result['messages']) self.assertEqual([ 1, 42, 2**31-1, 12345678, 2.0**33, .000001 ], values(self.read())) def test_negatives(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['-1'], ['-42'], [str(-2**31 + 1)], @@ -329,16 +329,16 @@ class test_float_field(ImporterCase): [str(-2**33)], ['-0.000001'], ]) - self.assertEqual(len(ids), 7) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 7) + self.assertFalse(result['messages']) self.assertEqual([ -1, -42, -(2**31 - 1), -(2**31), -12345678, -2.0**33, -.000001 ], values(self.read())) def test_nonsense(self): - ids, messages = self.import_(['value'], [['foobar']]) - self.assertIs(ids, False) - self.assertEqual(messages, [{ + result = self.import_(['value'], [['foobar']]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [{ 'type': 'error', 'rows': {'from': 0, 'to': 0}, 'record': 0, @@ -350,13 +350,13 @@ class test_string_field(ImporterCase): model_name = 'export.string.bounded' def test_empty(self): - ids, messages = self.import_(['value'], [['']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual([False], values(self.read())) def test_imported(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ [u'foobar'], [u'foobarbaz'], [u'Með suð í eyrum við spilum endalaust'], @@ -364,8 +364,8 @@ class test_string_field(ImporterCase): u"someone he can't pound a nail with a banana doesn't much " u"surprise him."] ]) - self.assertEqual(len(ids), 4) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 4) + self.assertFalse(result['messages']) self.assertEqual([ u"foobar", u"foobarbaz", @@ -377,14 +377,14 @@ class test_unbound_string_field(ImporterCase): model_name = 'export.string' def test_imported(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ [u'í dag viðrar vel til loftárása'], # ackbar.jpg [u"If they ask you about fun, you tell them – fun is a filthy" u" parasite"] ]) - self.assertEqual(len(ids), 2) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 2) + self.assertFalse(result['messages']) self.assertEqual([ u"í dag viðrar vel til loftárása", u"If they ask you about fun, you tell them – fun is a filthy parasite" @@ -394,9 +394,9 @@ class test_text(ImporterCase): model_name = 'export.text' def test_empty(self): - ids, messages = self.import_(['value'], [['']]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['']]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual([False], values(self.read())) def test_imported(self): @@ -406,9 +406,9 @@ class test_text(ImporterCase): u"snúninga 12 tommu vínylplötur (sem geta verið allt að 30 mín " u"hvor hlið).\n\nBreiðskífur eru stundum tvöfaldar og eru þær þá" u" gefnar út á tveimur geisladiskum eða tveimur vínylplötum.") - ids, messages = self.import_(['value'], [[s]]) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [[s]]) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) self.assertEqual([s], values(self.read())) class test_selection(ImporterCase): @@ -420,44 +420,44 @@ class test_selection(ImporterCase): ] def test_imported(self): - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['Qux'], ['Bar'], ['Foo'], ['2'], ]) - self.assertEqual(len(ids), 4) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 4) + self.assertFalse(result['messages']) self.assertEqual([3, 2, 1, 2], values(self.read())) def test_imported_translated(self): self.add_translations( 'export.selection,value', 'selection', 'fr_FR', *self.translations_fr) - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['toto'], ['tete'], ['titi'], ], context={'lang': 'fr_FR'}) - self.assertEqual(len(ids), 3) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 3) + self.assertFalse(result['messages']) self.assertEqual([3, 1, 2], values(self.read())) - ids, messages = self.import_(['value'], [['Foo']], context={'lang': 'fr_FR'}) - self.assertEqual(len(ids), 1) - self.assertFalse(messages) + result = self.import_(['value'], [['Foo']], context={'lang': 'fr_FR'}) + self.assertEqual(len(result['ids']), 1) + self.assertFalse(result['messages']) def test_invalid(self): - ids, messages = self.import_(['value'], [['Baz']]) - self.assertIs(ids, False) - self.assertEqual(messages, [message( + result = self.import_(['value'], [['Baz']]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [message( u"Value 'Baz' not found in selection field 'unknown'", moreinfo="Foo Bar Qux".split())]) - ids, messages = self.import_(['value'], [[42]]) - self.assertIs(ids, False) - self.assertEqual(messages, [message( + result = self.import_(['value'], [[42]]) + self.assertIs(result['ids'], False) + self.assertEqual(result['messages'], [message( u"Value '42' not found in selection field 'unknown'", moreinfo="Foo Bar Qux".split())]) @@ -476,12 +476,12 @@ class test_selection_function(ImporterCase): import does not actually know that the selection field uses a function """ # NOTE: conflict between a value and a label => pick first - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['3'], ["Grault"], ]) - self.assertEqual(len(ids), 2) - self.assertFalse(messages) + self.assertEqual(len(result['ids']), 2) + self.assertFalse(result['messages']) self.assertEqual( ['3', '1'], values(self.read())) @@ -492,17 +492,17 @@ class test_selection_function(ImporterCase): self.add_translations( 'export.selection,value', 'selection', 'fr_FR', *self.translations_fr) - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['titi'], ['tete'], ], context={'lang': 'fr_FR'}) - self.assertFalse(messages) - self.assertEqual(len(ids), 2) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 2) self.assertEqual(values(self.read()), ['1', '2']) - ids, messages = self.import_(['value'], [['Wheee']], context={'lang': 'fr_FR'}) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + result = self.import_(['value'], [['Wheee']], context={'lang': 'fr_FR'}) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) class test_m2o(ImporterCase): model_name = 'export.many2one' @@ -519,14 +519,14 @@ class test_m2o(ImporterCase): name2 = dict(self.registry('export.integer').name_get( self.cr, openerp.SUPERUSER_ID,[integer_id2]))[integer_id2] - ids , messages = self.import_(['value'], [ + result = self.import_(['value'], [ # import by name_get [name1], [name1], [name2], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 3) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 3) # correct ids assigned to corresponding records self.assertEqual([ (integer_id1, name1), @@ -541,18 +541,18 @@ class test_m2o(ImporterCase): xid = self.xid(ExportInteger.browse( self.cr, openerp.SUPERUSER_ID, [integer_id])[0]) - ids, messages = self.import_(['value/id'], [[xid]]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + result = self.import_(['value/id'], [[xid]]) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) b = self.browse() self.assertEqual(42, b[0].value.value) def test_by_id(self): integer_id = self.registry('export.integer').create( self.cr, openerp.SUPERUSER_ID, {'value': 42}) - ids, messages = self.import_(['value/.id'], [[integer_id]]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + result = self.import_(['value/.id'], [[integer_id]]) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) b = self.browse() self.assertEqual(42, b[0].value.value) @@ -568,12 +568,12 @@ class test_m2o(ImporterCase): # names should be the same self.assertEqual(name1, name2) - ids, messages = self.import_(['value'], [[name2]]) + result = self.import_(['value'], [[name2]]) self.assertEqual( - messages, + result['messages'], [message(u"Found multiple matches for field 'unknown' (2 matches)", type='warning')]) - self.assertEqual(len(ids), 1) + self.assertEqual(len(result['ids']), 1) self.assertEqual([ (integer_id1, name1) ], values(self.read())) @@ -588,55 +588,55 @@ class test_m2o(ImporterCase): self.cr, openerp.SUPERUSER_ID, {'value': 36}) # Because name_search all the things. Fallback schmallback - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ # import by id, without specifying it [integer_id1], [integer_id2], [integer_id1], ]) - self.assertEqual(messages, [ + self.assertEqual(result['messages'], [ message(u"No matching record found for name '%s' in field 'unknown'" % id, from_=index, to_=index, record=index) for index, id in enumerate([integer_id1, integer_id2, integer_id1])]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_sub_field(self): """ Does not implicitly create the record, does not warn that you can't import m2o subfields (at all)... """ - ids, messages = self.import_(['value/value'], [['42']]) - self.assertEqual(messages, [ + result = self.import_(['value/value'], [['42']]) + self.assertEqual(result['messages'], [ message(u"Can not create Many-To-One records indirectly, import " u"the field separately")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_fail_noids(self): - ids, messages = self.import_(['value'], [['nameisnoexist:3']]) - self.assertEqual(messages, [message( + result = self.import_(['value'], [['nameisnoexist:3']]) + self.assertEqual(result['messages'], [message( u"No matching record found for name 'nameisnoexist:3' " u"in field 'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) - ids, messages = self.import_(['value/id'], [['noxidhere']]) - self.assertEqual(messages, [message( + result = self.import_(['value/id'], [['noxidhere']]) + self.assertEqual(result['messages'], [message( u"No matching record found for external id 'noxidhere' " u"in field 'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) - ids, messages = self.import_(['value/.id'], [['66']]) - self.assertEqual(messages, [message( + result = self.import_(['value/.id'], [['66']]) + self.assertEqual(result['messages'], [message( u"No matching record found for database id '66' " u"in field 'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_fail_multiple(self): - ids, messages = self.import_( + result = self.import_( ['value', 'value/id'], [['somename', 'somexid']]) - self.assertEqual(messages, [message( + self.assertEqual(result['messages'], [message( u"Ambiguous specification for field 'unknown', only provide one of " u"name, external id or database id")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) class test_m2m(ImporterCase): model_name = 'export.many2many' @@ -656,14 +656,14 @@ class test_m2m(ImporterCase): id5 = self.registry('export.many2many.other').create( self.cr, openerp.SUPERUSER_ID, {'value': 99, 'str': 'record4'}) - ids, messages = self.import_(['value/.id'], [ + result = self.import_(['value/.id'], [ ['%d,%d' % (id1, id2)], ['%d,%d,%d' % (id1, id3, id4)], ['%d,%d,%d' % (id1, id2, id3)], ['%d' % id5] ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 4) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 4) ids = lambda records: [record.id for record in records] @@ -675,11 +675,11 @@ class test_m2m(ImporterCase): self.assertEqual(values(b[2].value), [3, 44, 84]) def test_noids(self): - ids, messages = self.import_(['value/.id'], [['42']]) - self.assertEqual(messages, [message( + result = self.import_(['value/.id'], [['42']]) + self.assertEqual(result['messages'], [message( u"No matching record found for database id '42' in field " u"'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_xids(self): M2O_o = self.registry('export.many2many.other') @@ -689,23 +689,23 @@ class test_m2m(ImporterCase): id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) records = M2O_o.browse(self.cr, openerp.SUPERUSER_ID, [id1, id2, id3, id4]) - ids, messages = self.import_(['value/id'], [ + result = self.import_(['value/id'], [ ['%s,%s' % (self.xid(records[0]), self.xid(records[1]))], ['%s' % self.xid(records[3])], ['%s,%s' % (self.xid(records[2]), self.xid(records[1]))], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 3) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 3) b = self.browse() self.assertEqual(values(b[0].value), [3, 44]) self.assertEqual(values(b[2].value), [44, 84]) def test_noxids(self): - ids, messages = self.import_(['value/id'], [['noxidforthat']]) - self.assertEqual(messages, [message( + result = self.import_(['value/id'], [['noxidforthat']]) + self.assertEqual(result['messages'], [message( u"No matching record found for external id 'noxidforthat' " u"in field 'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_names(self): M2O_o = self.registry('export.many2many.other') @@ -717,24 +717,24 @@ class test_m2m(ImporterCase): name = lambda record: dict(record.name_get())[record.id] - ids, messages = self.import_(['value'], [ + result = self.import_(['value'], [ ['%s,%s' % (name(records[1]), name(records[2]))], ['%s,%s,%s' % (name(records[0]), name(records[1]), name(records[2]))], ['%s,%s' % (name(records[0]), name(records[3]))], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 3) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 3) b = self.browse() self.assertEqual(values(b[1].value), [3, 44, 84]) self.assertEqual(values(b[2].value), [3, 9]) def test_nonames(self): - ids, messages = self.import_(['value'], [['wherethem2mhavenonames']]) - self.assertEqual(messages, [message( + result = self.import_(['value'], [['wherethem2mhavenonames']]) + self.assertEqual(result['messages'], [message( u"No matching record found for name 'wherethem2mhavenonames' in " u"field 'unknown'")]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_import_to_existing(self): M2O_o = self.registry('export.many2many.other') @@ -744,12 +744,12 @@ class test_m2m(ImporterCase): id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) xid = 'myxid' - ids, messages = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id1, id2)]]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) - ids, messages = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id3, id4)]]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + result = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id1, id2)]]) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) + result = self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id3, id4)]]) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) b = self.browse() self.assertEqual(len(b), 1) @@ -762,31 +762,31 @@ class test_o2m(ImporterCase): def test_name_get(self): s = u'Java is a DSL for taking large XML files and converting them ' \ u'to stack traces' - ids, messages = self.import_( + result = self.import_( ['const', 'value'], [['5', s]]) - self.assertEqual(messages, [message( + self.assertEqual(result['messages'], [message( u"No matching record found for name '%s' in field 'unknown'" % s)]) - self.assertIs(ids, False) + self.assertIs(result['ids'], False) def test_single(self): - ids, messages = self.import_(['const', 'value/value'], [ + result = self.import_(['const', 'value/value'], [ ['5', '63'] ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) (b,) = self.browse() self.assertEqual(b.const, 5) self.assertEqual(values(b.value), [63]) def test_multicore(self): - ids, messages = self.import_(['const', 'value/value'], [ + result = self.import_(['const', 'value/value'], [ ['5', '63'], ['6', '64'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 2) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 2) b1, b2 = self.browse() self.assertEqual(b1.const, 5) @@ -795,27 +795,27 @@ class test_o2m(ImporterCase): self.assertEqual(values(b2.value), [64]) def test_multisub(self): - ids, messages = self.import_(['const', 'value/value'], [ + result = self.import_(['const', 'value/value'], [ ['5', '63'], ['', '64'], ['', '65'], ['', '66'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) (b,) = self.browse() self.assertEqual(values(b.value), [63, 64, 65, 66]) def test_multi_subfields(self): - ids, messages = self.import_(['value/str', 'const', 'value/value'], [ + result = self.import_(['value/str', 'const', 'value/value'], [ ['this', '5', '63'], ['is', '', '64'], ['the', '', '65'], ['rhythm', '', '66'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) (b,) = self.browse() self.assertEqual(values(b.value), [63, 64, 65, 66]) @@ -833,11 +833,11 @@ class test_o2m(ImporterCase): 'str': 'Me', 'value': 262 }) - ids, messages = self.import_(['const', 'value/.id'], [ + result = self.import_(['const', 'value/.id'], [ ['42', '%d,%d' % (id1, id2)] ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) [b] = self.browse() self.assertEqual(b.const, 42) @@ -856,12 +856,12 @@ class test_o2m(ImporterCase): 'str': 'Me', 'value': 262 }) - ids, messages = self.import_(['const', 'value/.id'], [ + result = self.import_(['const', 'value/.id'], [ ['42', str(id1)], ['', str(id2)], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) [b] = self.browse() self.assertEqual(b.const, 42) @@ -878,12 +878,12 @@ class test_o2m(ImporterCase): 'str': 'Me', 'value': 262 }) - ids, messages = self.import_(['const', 'value/.id', 'value/value'], [ + result = self.import_(['const', 'value/.id', 'value/value'], [ ['42', str(id1), '1'], ['', str(id2), '2'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) [b] = self.browse() self.assertEqual(b.const, 42) @@ -894,21 +894,21 @@ class test_o2m_multiple(ImporterCase): model_name = 'export.one2many.multiple' def test_multi_mixed(self): - ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + result = self.import_(['const', 'child1/value', 'child2/value'], [ ['5', '11', '21'], ['', '12', '22'], ['', '13', '23'], ['', '14', ''], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) # Oh yeah, that's the stuff [b] = self.browse() self.assertEqual(values(b.child1), [11, 12, 13, 14]) self.assertEqual(values(b.child2), [21, 22, 23]) def test_multi(self): - ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + result = self.import_(['const', 'child1/value', 'child2/value'], [ ['5', '11', '21'], ['', '12', ''], ['', '13', ''], @@ -916,15 +916,15 @@ class test_o2m_multiple(ImporterCase): ['', '', '22'], ['', '', '23'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) [b] = self.browse() self.assertEqual(values(b.child1), [11, 12, 13, 14]) self.assertEqual(values(b.child2), [21, 22, 23]) def test_multi_fullsplit(self): - ids, messages = self.import_(['const', 'child1/value', 'child2/value'], [ + result = self.import_(['const', 'child1/value', 'child2/value'], [ ['5', '11', ''], ['', '12', ''], ['', '13', ''], @@ -933,8 +933,8 @@ class test_o2m_multiple(ImporterCase): ['', '', '22'], ['', '', '23'], ]) - self.assertFalse(messages) - self.assertEqual(len(ids), 1) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) [b] = self.browse() self.assertEqual(b.const, 5) From 292252eb7dd18de14a3d4504e33c7b8df2936fbc Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 24 Sep 2012 17:37:29 +0200 Subject: [PATCH 280/726] [ADD] Make things work .... or not ? bzr revid: fme@openerp.com-20120924153729-e7lsjvfxfpjzrpm7 --- .../auth_oauth_provider/controllers/main.py | 31 ++++++++++++++++--- addons/auth_oauth_provider/res_users.py | 12 +++++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/addons/auth_oauth_provider/controllers/main.py b/addons/auth_oauth_provider/controllers/main.py index 63bf3cad61c..7ca4ab75d56 100644 --- a/addons/auth_oauth_provider/controllers/main.py +++ b/addons/auth_oauth_provider/controllers/main.py @@ -23,14 +23,27 @@ try: import openerp.addons.web.common.http as openerpweb except ImportError: - import web.common.http as openerpweb # noqa + import web.common.http as openerpweb + +import openerp.modules.registry +from openerp import SUPERUSER_ID import simplejson - +import werkzeug +import urllib class AuthOAuthProvider(openerpweb.Controller): _cp_path = '/oauth2' + @openerpweb.httprequest + def auth(self, req, **kw): + # TODO: if logged and approval_prompt == auto then return get_token and redirect + search = req.params.copy() + if req.debug: + search['debug'] = 1 + redirect_url = '/?' + urllib.urlencode(search) + '#action=oauth2_auth' + return werkzeug.utils.redirect(redirect_url, 303) + @openerpweb.jsonrequest def get_token(self, req, client_id="", scope="", **kw): token = req.session.model('res.users').auth_oauth_provider_get_token(client_id, scope) @@ -39,8 +52,16 @@ class AuthOAuthProvider(openerpweb.Controller): } @openerpweb.httprequest - def tokeninfo(self, req, access_token="", **kw): - info = req.session.model('res.users').auth_oauth_provider_tokeninfo(access_token) - return simplejson.dumps(info) + def tokeninfo(self, req, dbname=None, access_token=None, **kw): + if not dbname or not access_token: + return simplejson.dumps({ "error": "No 'dbname' or 'access_token' url parameters specified." }) + try: + registry = openerp.modules.registry.RegistryManager.get(dbname) + with registry.cursor() as cr: + u = registry.get('res.users') + info = u.auth_oauth_provider_tokeninfo(cr, SUPERUSER_ID, access_token, kw) + return simplejson.dumps(info) + except Exception, e: + return simplejson.dumps({ "error": e.message }) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth_provider/res_users.py b/addons/auth_oauth_provider/res_users.py index 3831a6a97d0..983672e0261 100644 --- a/addons/auth_oauth_provider/res_users.py +++ b/addons/auth_oauth_provider/res_users.py @@ -40,14 +40,20 @@ class res_users(osv.osv): }, context=context) return token - def auth_oauth_provider_tokeninfo(self, cr, uid, access_token="", context=None): - user = self.browse(cr, uid, [uid], context=context) + def auth_oauth_provider_tokeninfo(self, cr, uid, access_token, context=None): + user_id = self.search(cr, uid, [('last_oauth_token', '=', access_token)], context=context) + if len(user_id) != 1: + return { + "error": "invalid_token" + } + user = self.browse(cr, uid, user_id[0], context=context) if access_token == user.last_oauth_token: return { "user_id": uid, "scope": user.last_oauth_token_scope, + "email": user.partner_id.email or '', # TODO: should deliver only according to scopes + "scope": user.last_oauth_token_scope, #"audience": "8819981768.apps.googleusercontent.com", - #"scope": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", #"expires_in": 436 } else: From 1b5939817ff82d4356dd4da00ea7d7a9bd448a3b Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 24 Sep 2012 18:02:13 +0200 Subject: [PATCH 281/726] [FIX] Return correct userid in tokeninfo bzr revid: fme@openerp.com-20120924160213-kfjdi6s01mcic9jp --- addons/auth_oauth_provider/controllers/main.py | 1 - addons/auth_oauth_provider/res_users.py | 2 +- addons/auth_oauth_provider/static/src/js/oauth_provider.js | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/auth_oauth_provider/controllers/main.py b/addons/auth_oauth_provider/controllers/main.py index 7ca4ab75d56..944e3e44bf9 100644 --- a/addons/auth_oauth_provider/controllers/main.py +++ b/addons/auth_oauth_provider/controllers/main.py @@ -37,7 +37,6 @@ class AuthOAuthProvider(openerpweb.Controller): @openerpweb.httprequest def auth(self, req, **kw): - # TODO: if logged and approval_prompt == auto then return get_token and redirect search = req.params.copy() if req.debug: search['debug'] = 1 diff --git a/addons/auth_oauth_provider/res_users.py b/addons/auth_oauth_provider/res_users.py index 983672e0261..38200597730 100644 --- a/addons/auth_oauth_provider/res_users.py +++ b/addons/auth_oauth_provider/res_users.py @@ -49,7 +49,7 @@ class res_users(osv.osv): user = self.browse(cr, uid, user_id[0], context=context) if access_token == user.last_oauth_token: return { - "user_id": uid, + "user_id": user.id, "scope": user.last_oauth_token_scope, "email": user.partner_id.email or '', # TODO: should deliver only according to scopes "scope": user.last_oauth_token_scope, diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js index a5e05c60283..f08b098efed 100644 --- a/addons/auth_oauth_provider/static/src/js/oauth_provider.js +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -21,7 +21,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ // that should be displayed in the approval confirmation dialog. if (!this._error) { - // params.approval_prompt TODO + // params.approval_prompt TODO --> add 'none' (default) // TODO: get client_id and scope this.$('.oe_oauth_provider_approval').show().on('click', '.oe_oauth_provider_allow', function() { instance.session.rpc('/oauth2/get_token', { From a129da845af5880ad3c7bca7bf53f1874bbccda6 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 24 Sep 2012 18:15:18 +0200 Subject: [PATCH 282/726] [ACTIVATE] Yes ! Activate ! bzr revid: fme@openerp.com-20120924161518-n0096bt1j2n04cpa --- addons/auth_oauth_provider/static/src/js/oauth_provider.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js index f08b098efed..b81b824cd88 100644 --- a/addons/auth_oauth_provider/static/src/js/oauth_provider.js +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -57,8 +57,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ new_params.state = params.state; } var redirect = a.protocol + '//' + a.host + a.pathname + '?' + $.param(new_params) + a.hash; - //window.location = redirect; - console.log("redirect to", redirect); + window.location = redirect; }, error: function(msg) { this._error = true; From e6c8f1739a70ba8c0252ed8ace839c30f7e794dc Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 09:42:56 +0200 Subject: [PATCH 283/726] [ADD] 'more info' action to m2o, o2m and m2m linking failures bzr revid: xmo@openerp.com-20120925074256-18puerjbfo3om265 --- openerp/addons/base/ir/ir_fields.py | 31 +++++++------- .../addons/test_impex/tests/test_load.py | 42 +++++++++---------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 2256542533b..cec74e8976e 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -201,6 +201,21 @@ class ir_fields_converter(orm.Model): id, _name = ids[0] else: raise Exception(u"Unknown sub-field '%s'" % subfield) + + if id is None: + raise ValueError( + _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") + % {'field_type': field_type, 'value': value}, { + 'moreinfo': { + 'type': 'ir.actions.act_window', + 'target': 'new', + 'res_model': column._obj, + 'view_mode': 'tree,form', + 'view_type': 'form', + 'views': [(False, 'tree', (False, 'form'))], + 'help': _(u"See all possible values") + } + }) return id, field_type def _referencing_subfield(self, record): @@ -235,12 +250,8 @@ class ir_fields_converter(orm.Model): reference = record[subfield] id, subfield_type = self.db_id_for( cr, uid, model, column, subfield, reference, context=context) - - if id is None: - raise ValueError( - _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") - % {'field_type': subfield_type, 'value': reference}) return id + def _str_to_many2many(self, cr, uid, model, column, value, context=None): [record] = value @@ -250,13 +261,9 @@ class ir_fields_converter(orm.Model): for reference in record[subfield].split(','): id, subfield_type = self.db_id_for( cr, uid, model, column, subfield, reference, context=context) - if id is None: - raise ValueError( - _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") - % {'field_type': subfield_type, 'value': reference}) ids.append(id) - return [(6, 0, ids)] + def _str_to_one2many(self, cr, uid, model, column, records, context=None): commands = [] @@ -278,10 +285,6 @@ class ir_fields_converter(orm.Model): reference = record[subfield] id, subfield_type = self.db_id_for( cr, uid, model, column, subfield, reference, context=context) - if id is None: - raise ValueError( - _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") - % {'field_type': subfield_type, 'value': reference}) writable = exclude_ref_fields(record) if id: diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index 060b32c48f5..f625ecb7043 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -9,18 +9,16 @@ def message(msg, type='error', from_=0, to_=0, record=0, field='value', **kwargs return dict(kwargs, type=type, rows={'from': from_, 'to': to_}, record=record, field=field, message=msg) - -def error(row, message, record=None, **kwargs): - """ Failed import of the record ``record`` at line ``row``, with the error - message ``message`` - - :param str message: - :param dict record: - """ - return ( - -1, dict(record or {}, **kwargs), - "Line %d : %s" % (row, message), - '') +def moreaction(model): + return { + 'type': 'ir.actions.act_window', + 'target': 'new', + 'res_model': model, + 'view_mode': 'tree,form', + 'view_type': 'form', + 'views': [(False, 'tree', (False, 'form'))], + 'help': u"See all possible values" + } def values(seq, field='value'): return [item[field] for item in seq] @@ -596,7 +594,8 @@ class test_m2o(ImporterCase): ]) self.assertEqual(result['messages'], [ message(u"No matching record found for name '%s' in field 'unknown'" % id, - from_=index, to_=index, record=index) + from_=index, to_=index, record=index, + moreinfo=moreaction('export.integer')) for index, id in enumerate([integer_id1, integer_id2, integer_id1])]) self.assertIs(result['ids'], False) @@ -614,19 +613,19 @@ class test_m2o(ImporterCase): result = self.import_(['value'], [['nameisnoexist:3']]) self.assertEqual(result['messages'], [message( u"No matching record found for name 'nameisnoexist:3' " - u"in field 'unknown'")]) + u"in field 'unknown'", moreinfo=moreaction('export.integer'))]) self.assertIs(result['ids'], False) result = self.import_(['value/id'], [['noxidhere']]) self.assertEqual(result['messages'], [message( u"No matching record found for external id 'noxidhere' " - u"in field 'unknown'")]) + u"in field 'unknown'", moreinfo=moreaction('export.integer'))]) self.assertIs(result['ids'], False) result = self.import_(['value/.id'], [['66']]) self.assertEqual(result['messages'], [message( u"No matching record found for database id '66' " - u"in field 'unknown'")]) + u"in field 'unknown'", moreinfo=moreaction('export.integer'))]) self.assertIs(result['ids'], False) def test_fail_multiple(self): @@ -678,7 +677,7 @@ class test_m2m(ImporterCase): result = self.import_(['value/.id'], [['42']]) self.assertEqual(result['messages'], [message( u"No matching record found for database id '42' in field " - u"'unknown'")]) + u"'unknown'", moreinfo=moreaction('export.many2many.other'))]) self.assertIs(result['ids'], False) def test_xids(self): @@ -703,8 +702,8 @@ class test_m2m(ImporterCase): def test_noxids(self): result = self.import_(['value/id'], [['noxidforthat']]) self.assertEqual(result['messages'], [message( - u"No matching record found for external id 'noxidforthat' " - u"in field 'unknown'")]) + u"No matching record found for external id 'noxidforthat' in field" + u" 'unknown'", moreinfo=moreaction('export.many2many.other'))]) self.assertIs(result['ids'], False) def test_names(self): @@ -733,7 +732,7 @@ class test_m2m(ImporterCase): result = self.import_(['value'], [['wherethem2mhavenonames']]) self.assertEqual(result['messages'], [message( u"No matching record found for name 'wherethem2mhavenonames' in " - u"field 'unknown'")]) + u"field 'unknown'", moreinfo=moreaction('export.many2many.other'))]) self.assertIs(result['ids'], False) def test_import_to_existing(self): @@ -766,7 +765,8 @@ class test_o2m(ImporterCase): ['const', 'value'], [['5', s]]) self.assertEqual(result['messages'], [message( - u"No matching record found for name '%s' in field 'unknown'" % s)]) + u"No matching record found for name '%s' in field 'unknown'" % s, + moreinfo=moreaction('export.one2many.child'))]) self.assertIs(result['ids'], False) def test_single(self): From 6a99c09facf3c098dadba35c1728e14f1a92e7ef Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 25 Sep 2012 10:23:57 +0200 Subject: [PATCH 284/726] [IMP] Use uuid for tokens bzr revid: fme@openerp.com-20120925082357-g1yfq8udbwdda296 --- addons/auth_oauth_provider/res_users.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/addons/auth_oauth_provider/res_users.py b/addons/auth_oauth_provider/res_users.py index 38200597730..20d9e9c7ade 100644 --- a/addons/auth_oauth_provider/res_users.py +++ b/addons/auth_oauth_provider/res_users.py @@ -19,21 +19,19 @@ # ############################################################################## from openerp.osv import osv, fields -import random -import string +import uuid class res_users(osv.osv): _inherit = 'res.users' _columns = { # TODO: partial implementation supporting only one client_id for the moment. - 'last_oauth_token': fields.char('Last OAuth Token', readonly=True, invisible=True), + 'last_oauth_token': fields.char('Last OAuth Token', size=32, readonly=True, invisible=True), 'last_oauth_token_scope': fields.char('Last OAuth Token Scope', readonly=True, invisible=True), } def auth_oauth_provider_get_token(self, cr, uid, client_id="", scope="", context=None): - chars = string.ascii_uppercase + string.ascii_lowercase + string.digits - token = ''.join(random.choice(chars) for x in range(random.randrange(16, 24))) + token = str(uuid.uuid4()).replace('-', '') self.write(cr, uid, [uid], { "last_oauth_token": token, "last_oauth_token_scope": scope, From 4525190e726a3f9fadeade2fba40c41a69a4bb72 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 25 Sep 2012 10:58:09 +0200 Subject: [PATCH 285/726] [IMP] mail: auto display subtypes on subscription (web) bzr revid: chm@openerp.com-20120925085809-u8f7tvtbdxnftbu4 --- addons/mail/mail_thread.py | 36 +++++++++++++++++---- addons/mail/static/src/js/mail_followers.js | 30 ++++++++++------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 71d4bfd099b..665ca664994 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -625,10 +625,17 @@ class mail_thread(osv.AbstractModel): ``(name,content)``, where content is NOT base64 encoded :return: ID of newly created mail.message """ + # message_post + # [26] False notification mt_crm_stage False + + # message_post + # [26] False notification mt_crm_won False + context = context or {} attachments = attachments or [] assert (not thread_id) or isinstance(thread_id, (int, long)) or \ (isinstance(thread_id, (list, tuple)) and len(thread_id) == 1), "Invalid thread_id" + if isinstance(thread_id, (list, tuple)): thread_id = thread_id and thread_id[0] @@ -652,9 +659,19 @@ class mail_thread(osv.AbstractModel): else: subtype_id = False + + #auto link messages for same id and object + messages = self.pool.get('mail.message') + model = context.get('thread_model', self._name) if thread_id else False + if model != 'res.partner': + message_ids = messages.search(cr, uid, ['&',('res_id', '=', thread_id),('model','=',model)], context=context) + if len(message_ids): + parent_id = min(message_ids) + + values = kwargs values.update({ - 'model': context.get('thread_model', self._name) if thread_id else False, + 'model': model, 'res_id': thread_id or False, 'body': body, 'subject': subject, @@ -666,12 +683,22 @@ class mail_thread(osv.AbstractModel): # Avoid warnings about non-existing fields for x in ('from', 'to', 'cc'): values.pop(x, None) - return self.pool.get('mail.message').create(cr, uid, values, context=context) + + print "------------------------------------------" + print values, "mail_thread 688" + print "--------≃============----------------------------------" + + return messages.create(cr, uid, values, context=context) #------------------------------------------------------ # Followers API #------------------------------------------------------ + def get_message_subtypes(self, cr, uid, ids, context=None): + """ message_subtype_data: data about document subtypes: which are + available, which are followed if any """ + return self._get_subscription_data(cr, uid, ids, None, None, context=context) + def message_subscribe_users(self, cr, uid, ids, user_ids=None, subtype_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not provided, subscribe uid instead. """ @@ -680,11 +707,6 @@ class mail_thread(osv.AbstractModel): partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] return self.message_subscribe(cr, uid, ids, partner_ids, subtype_ids=subtype_ids, context=context) - def get_message_subtypes(self, cr, uid, ids, context=None): - """ message_subtype_data: data about document subtypes: which are - available, which are followed if any """ - return self._get_subscription_data(cr, uid, ids, None, None, context=context) - def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None): """ Add partners to the records followers. """ self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 85bd4c37987..4ceb936c623 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -51,11 +51,11 @@ openerp_mail_followers = function(session, mail) { bind_events: function() { var self = this; - this.$el.find('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); self.clear_subtypes(); }) + this.$el.find('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); }) .mouseover(function () { $(this).removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover').find('p').html('Unfollow');}) .mouseleave(function () { $(this).removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout').find('p').html('Following'); }); - this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); self.clear_subtypes(); }); + this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); }); this.$el.on('click', 'ul.oe_mail_subtypes input', function () {self.do_update_subscription(); }) this.$el.on('click', 'button.oe_mail_button_invite', function(event) { action = { @@ -101,9 +101,9 @@ openerp_mail_followers = function(session, mail) { return false; }, - fetch_followers: function (value_, message_is_follower) { - this.value = value_; - this.message_is_follower = message_is_follower || (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); + fetch_followers: function (value_) { + this.value = value_ || {}; + this.message_is_follower = (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers'), this.proxy('display_generic')); }, @@ -163,7 +163,7 @@ openerp_mail_followers = function(session, mail) { }, /** Display subtypes: {'name': default, followed} */ - display_subtypes: function () { + display_subtypes: function (visible) { var self = this; var recthread_subtypes = self.$el.find('.oe_mail_recthread_subtypes'); subtype_list_ul = self.$el.find('ul.oe_mail_subtypes'); @@ -180,21 +180,27 @@ openerp_mail_followers = function(session, mail) { } }, - clear_subtypes: function(){ - this.$el.find('ul.oe_mail_subtypes').empty(); - this.hidden_subtypes(); - }, - hidden_subtypes: function (){ this.$el.find('.oe_mail_recthread_subtypes').hide(); }, do_follow: function () { + var self =this; + _(this.$el.find('.oe_msg_subtype_check')).each(function(record){ + $(record).attr('checked','checked'); + }); var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, undefined, context]).pipe(this.proxy('read_value')); + return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, undefined, context]).pipe(function(value_){ + self.read_value(value_); + if(!self.$el.find('.oe_mail_recthread_subtypes').is(":visible")) + self.display_subtypes(true); + }); }, do_unfollow: function () { + _(this.$el.find('.oe_msg_subtype_check')).each(function(record){ + $(record).attr('checked',false); + }); var context = new session.web.CompoundContext(this.build_context(), {}); return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value')); }, From bf3cb4bcd6de46ec86b9bb335008a3722e817276 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 25 Sep 2012 11:12:36 +0200 Subject: [PATCH 286/726] [FIX] mail: rpc with not false value bzr revid: chm@openerp.com-20120925091236-l9ywccbyjsoa31ph --- addons/mail/static/src/js/mail_followers.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 4ceb936c623..5836bd94ba1 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -104,7 +104,8 @@ openerp_mail_followers = function(session, mail) { fetch_followers: function (value_) { this.value = value_ || {}; this.message_is_follower = (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); - return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers'), this.proxy('display_generic')); + if(value_) + return this.ds_follow.call('read', [this.value, ['name', 'user_ids']]).pipe(this.proxy('display_followers'), this.proxy('display_generic')); }, /* Display generic info about follower, for people not having access to res_partner */ From a19717019449a86973269ef7cefa492dd44ca97d Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 25 Sep 2012 11:51:19 +0200 Subject: [PATCH 287/726] [ADD] Added OpenERP Online oauth provider + openerp zocial css bzr revid: fme@openerp.com-20120925095119-erlvy2vjqxrkjvy6 --- addons/auth_oauth/__openerp__.py | 5 +++- addons/auth_oauth/auth_oauth_data.xml | 9 +++++++ .../auth_oauth/static/src/css/auth_oauth.css | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 addons/auth_oauth/static/src/css/auth_oauth.css diff --git a/addons/auth_oauth/__openerp__.py b/addons/auth_oauth/__openerp__.py index d43815e8018..c8da9c65d4a 100644 --- a/addons/auth_oauth/__openerp__.py +++ b/addons/auth_oauth/__openerp__.py @@ -38,7 +38,10 @@ Allow users to login through Google OAuth2. 'security/ir.model.access.csv' ], 'js': ['static/src/js/auth_oauth.js'], - 'css': ['static/lib/zocial/css/zocial.css'], + 'css': [ + 'static/lib/zocial/css/zocial.css', + 'static/src/css/auth_oauth.css', + ], 'qweb': ['static/src/xml/auth_oauth.xml'], 'installable': True, 'auto_install': False, diff --git a/addons/auth_oauth/auth_oauth_data.xml b/addons/auth_oauth/auth_oauth_data.xml index 7bb95192e5d..86b0f6c593e 100644 --- a/addons/auth_oauth/auth_oauth_data.xml +++ b/addons/auth_oauth/auth_oauth_data.xml @@ -2,6 +2,15 @@ + + OpenERP + https://openerp.my.openerp.com/oauth2/auth + userinfo + https://openerp.my.openerp.com/oauth2/tokeninfo + + zocial openerp + Sign in with OpenERP Online + Facebook Graph https://www.facebook.com/dialog/oauth diff --git a/addons/auth_oauth/static/src/css/auth_oauth.css b/addons/auth_oauth/static/src/css/auth_oauth.css new file mode 100644 index 00000000000..ffec2a0a1e8 --- /dev/null +++ b/addons/auth_oauth/static/src/css/auth_oauth.css @@ -0,0 +1,26 @@ +.zocial.openerp:before { + content: "\E02E"; + font-style: italic; +} + +a.zocial.openerp { + float: right; + border: 1px solid #222222; + color: white; + margin: 0; + background-color: #b92020; + background-image: -webkit-gradient(linear, left top, left bottom, from(#b92020), to(#600606)); + background-image: -webkit-linear-gradient(top, #b92020, #600606); + background-image: -moz-linear-gradient(top, #b92020, #600606); + background-image: -ms-linear-gradient(top, #b92020, #600606); + background-image: -o-linear-gradient(top, #b92020, #600606); + background-image: linear-gradient(to bottom, #b92020, #600606); + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; + text-shadow: none; + font-weight: normal; +} From 359b4a44aa2d10cac6a0ce9bd623ac6b4e1a17d7 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 12:02:32 +0200 Subject: [PATCH 288/726] [ADD] ability to convert postgres error messages to human-readable ones also convert 'violates not-null constraint' to something about fields being required bzr revid: xmo@openerp.com-20120925100232-bfmxcxda65cki5kv --- openerp/osv/orm.py | 31 ++++++++++++++++++- openerp/tests/addons/test_impex/models.py | 1 + .../addons/test_impex/tests/test_load.py | 15 +++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index b824be91b96..25974760bdd 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -42,6 +42,7 @@ """ import calendar +import collections import copy import datetime import itertools @@ -1493,6 +1494,7 @@ class BaseModel(object): fields = map(fix_import_export_id_paths, fields) ModelData = self.pool['ir.model.data'] + fg = self.fields_get(cr, uid, context=context) mode = 'init' current_module = '' @@ -1509,11 +1511,16 @@ class BaseModel(object): current_module, record, mode=mode, xml_id=xid, noupdate=noupdate, res_id=id, context=context)) cr.execute('RELEASE SAVEPOINT model_load_save') + except psycopg2.Warning, e: + cr.execute('ROLLBACK TO SAVEPOINT model_load_save') + messages.append(dict(info, type='warning', message=str(e))) except psycopg2.Error, e: # Failed to write, log to messages, rollback savepoint (to # avoid broken transaction) and keep going cr.execute('ROLLBACK TO SAVEPOINT model_load_save') - messages.append(dict(info, type="error", message=str(e))) + messages.append(dict( + info, type="error", + **PGERROR_TO_OE[e.pgcode](self, fg, info, e))) if any(message['type'] == 'error' for message in messages): cr.execute('ROLLBACK TO SAVEPOINT model_load') ids = False @@ -5390,4 +5397,26 @@ class ImportWarning(Warning): """ Used to send warnings upwards the stack during the import process """ pass + + +def convert_pgerror_23502(model, fields, info, e): + m = re.match(r'^null value in column "(?P\w+)" violates ' + r'not-null constraint\n$', + str(e)) + if not m or m.group('field') not in fields: + return {'message': unicode(e)} + field = fields[m.group('field')] + return { + 'message': _(u"Missing required value for the field '%(field)s'") % { + 'field': field['string'] + }, + 'field': m.group('field'), + } + +PGERROR_TO_OE = collections.defaultdict( + # shape of mapped converters + lambda: (lambda model, fvg, info, pgerror: {'message': unicode(pgerror)}), { + # not_null_violation + '23502': convert_pgerror_23502, +}) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/addons/test_impex/models.py b/openerp/tests/addons/test_impex/models.py index 37894ccb78c..c56ddc649e2 100644 --- a/openerp/tests/addons/test_impex/models.py +++ b/openerp/tests/addons/test_impex/models.py @@ -17,6 +17,7 @@ models = [ ('float', fields.float()), ('decimal', fields.float(digits=(16, 3))), ('string.bounded', fields.char('unknown', size=16)), + ('string.required', fields.char('unknown', size=None, required=True)), ('string', fields.char('unknown', size=None)), ('date', fields.date()), ('datetime', fields.datetime()), diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index f625ecb7043..eb777a57988 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -388,6 +388,21 @@ class test_unbound_string_field(ImporterCase): u"If they ask you about fun, you tell them – fun is a filthy parasite" ], values(self.read())) +class test_required_string_field(ImporterCase): + model_name = 'export.string.required' + + def test_empty(self): + result = self.import_(['value'], [[]]) + self.assertEqual(result['messages'], [message( + u"Missing required value for the field 'unknown'")]) + self.assertIs(result['ids'], False) + + def test_not_provided(self): + result = self.import_(['const'], [['12']]) + self.assertEqual(result['messages'], [message( + u"Missing required value for the field 'unknown'")]) + self.assertIs(result['ids'], False) + class test_text(ImporterCase): model_name = 'export.text' From 404c2c2dbaa21d1520ac89430a7f565e1008d471 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 25 Sep 2012 12:32:11 +0200 Subject: [PATCH 289/726] [IMP] Minor css change bzr revid: fme@openerp.com-20120925103211-l1yfgp9s7ro3twuo --- addons/auth_oauth/static/src/css/auth_oauth.css | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/auth_oauth/static/src/css/auth_oauth.css b/addons/auth_oauth/static/src/css/auth_oauth.css index ffec2a0a1e8..ef0d648e950 100644 --- a/addons/auth_oauth/static/src/css/auth_oauth.css +++ b/addons/auth_oauth/static/src/css/auth_oauth.css @@ -1,6 +1,7 @@ .zocial.openerp:before { content: "\E02E"; font-style: italic; + text-shadow: 0 1px 1px black; } a.zocial.openerp { From aceae3501efeece3366db5a478bf450067e37301 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 12:40:13 +0200 Subject: [PATCH 290/726] [IMP] auth_signup: extend the login form to allow signups bzr revid: rco@openerp.com-20120925104013-f2vfqcjknx7zyo26 --- addons/auth_signup/controllers/main.py | 49 +++++-- addons/auth_signup/res_users.py | 121 ++++++++---------- .../auth_signup/static/src/js/auth_signup.js | 104 ++++++++------- .../static/src/xml/auth_signup.xml | 43 +++---- 4 files changed, 172 insertions(+), 145 deletions(-) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 821ef44f459..343c660ff7d 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -1,25 +1,58 @@ -import logging - -import werkzeug.urls +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## +from openerp import SUPERUSER_ID from openerp.modules.registry import RegistryManager from openerp.addons.web.controllers.main import login_and_redirect import openerp.addons.web.common.http as openerpweb -from openerp import SUPERUSER_ID +import werkzeug + +import logging _logger = logging.getLogger(__name__) -class OpenIDController(openerpweb.Controller): +class Controller(openerpweb.Controller): _cp_path = '/auth_signup' + @openerpweb.jsonrequest + def retrieve(self, req, dbname, token): + """ retrieve the user info (name, login or email) corresponding to a signup token """ + registry = RegistryManager.get(dbname) + user_info = None + with registry.cursor() as cr: + res_partner = registry.get('res.partner') + user_info = res_partner.signup_retrieve_info(cr, SUPERUSER_ID, token) + user_info.update(db=dbname, token=token) + return user_info + @openerpweb.httprequest - def signup(self, req, dbname, name, login, password): + def signup(self, req, dbname, token, name, login, password): + """ sign up a user (new or existing), and log it in """ url = '/' registry = RegistryManager.get(dbname) with registry.cursor() as cr: try: - Users = registry.get('res.users') - credentials = Users.auth_signup(cr, SUPERUSER_ID, name, login, password) + res_users = registry.get('res.users') + values = {'name': name, 'login': login, 'password': password} + credentials = res_users.signup(cr, SUPERUSER_ID, values, token) cr.commit() return login_and_redirect(req, *credentials) except AttributeError: diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py index f37c547ad8c..600ed9c000e 100644 --- a/addons/auth_signup/res_users.py +++ b/addons/auth_signup/res_users.py @@ -29,8 +29,8 @@ import random import urlparse def random_token(): - # the token has an entropy of 120 bits (6 bits/char * 20 chars) - chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + # the token has an entropy of about 120 bits (6 bits/char * 20 chars) + chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' return ''.join(random.choice(chars) for i in xrange(20)) def now(): @@ -39,12 +39,25 @@ def now(): class res_partner(osv.Model): _inherit = 'res.partner' + + def signup_get_url(self, cr, uid, partner_ids, name, arg, context=None): + """ determine a url for the partner_id to sign up """ + base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + res = {} + for partner in self.browse(cr, uid, partner_ids, context): + token = partner.signup_token + if not token: + token = self._signup_generate_token(cr, uid, partner.id, context=context) + res[partner.id] = urlparse.urljoin(base_url, '#action=login&db=%s&token=%s' % (cr.dbname, token)) + return res + _columns = { 'signup_token': fields.char(size=24, string='Signup Ticket'), 'signup_expiration': fields.datetime(string='Signup Expiration'), + 'signup_url': fields.function(signup_get_url, type='char', string='Signup URL'), } - def signup_generate_token(self, cr, uid, partner_id, context=None): + def _signup_generate_token(self, cr, uid, partner_id, expiration=False, context=None): """ generate a new token for a partner, and return it :param partner_id: the partner id :param expiration: the expiration datetime of the token (string, optional) @@ -52,25 +65,45 @@ class res_partner(osv.Model): """ # generate a unique token token = random_token() - while self.signup_retrieve_partner(cr, uid, token, context): + while self._signup_retrieve_partner(cr, uid, token, context=context): token = random_token() self.write(cr, uid, [partner_id], {'signup_token': token, 'signup_expiration': expiration}, context=context) return token - def signup_retrieve_partner(self, cr, uid, token, raise_exception=False, context=None): - """ find the partner corresponding to a token, and return its partner id or False """ + def _signup_retrieve_partner(self, cr, uid, token, raise_exception=False, context=None): + """ find the partner corresponding to a token, and check its validity + :return: partner (browse record) or False (if raise_exception is False) + :raise: when token not valid (if raise_exception is True) + """ partner_ids = self.search(cr, uid, [('signup_token', '=', token)], context=context) - return partner_ids and partner_ids[0] or False + if not partner_ids: + if raise_exception: + raise Exception("Signup token '%s' is not valid" % token) + return False + partner = self.browse(cr, uid, partner_ids[0], context) + if partner.signup_expiration and partner.signup_expiration < now(): + if raise_exception: + raise Exception("Signup token '%s' is no longer valid" % token) + return False + return partner - def signup_get_url(self, cr, uid, partner_id, context): - """ determine a url for the partner_id to sign up """ - base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') - token = self.browse(cr, uid, partner_id, context).signup_token - if not token: - token = self.signup_generate_token(cr, uid, partner_id, context=context) - return urlparse.urljoin(base_url, '/login?db=%s#action=signup&token=%s' % (cr.dbname, token)) + def signup_retrieve_info(self, cr, uid, token, context=None): + """ retrieve the user info about the token + :return: either {'name': ..., 'login': ...} if a user exists for that token, + or {'name': ..., 'email': ...} otherwise + """ + partner = self._signup_retrieve_partner(cr, uid, token, raise_exception=True, context=None) + if partner.user_ids: + return {'name': partner.name, 'login': partner.user_ids[0].login} + else: + return {'name': partner.name, 'email': partner.email} - def signup(self, cr, values, token=None, context=None): + + +class res_users(osv.Model): + _inherit = 'res.users' + + def signup(self, cr, uid, values, token=None, context=None): """ signup a user, to either: - create a new user (no token), or - create a user for a partner (with token, but no user for partner), or @@ -84,13 +117,8 @@ class res_partner(osv.Model): if token: # signup with a token: find the corresponding partner id - partner_id = self.signup_retrieve_partner(cr, uid, token, context=None) - if not partner_id: - raise Exception('Signup token is not valid') - partner = self.browse(cr, uid, partner_id, context) - if partner.signup_expiration and partner.signup_expiration < now(): - raise Exception('Signup token is no longer valid') - + res_partner = self.pool.get('res.partner') + partner = res_partner._signup_retrieve_partner(cr, uid, token, raise_exception=True, context=None) if partner.user_ids: # user exists, modify its password and clear token partner.user_ids[0].write({ @@ -129,51 +157,6 @@ class res_partner(osv.Model): template_user_id = ir_config_parameter.get_param(cr, uid, 'auth_signup.template_user_id') assert template_user_id, 'Signup: missing template user' - values['active'] = True - return self.pool.get('res.users').copy(cr, uid, template_user_id, values, context=context) + values.update({'active': True, 'signup_token': False, 'signup_expiration': False}) + return self.copy(cr, uid, template_user_id, values, context=context) - - -class res_users(osv.Model): - _inherit = 'res.users' - - def auth_signup_create(self, cr, uid, new_user, context=None): - # new_user: - # login - # email - # name (optional) - # partner_id (optional) - # groups (optional) - # sign (for partner_id and groups) - # - user_template_id = self.pool.get('ir.config_parameter').get_param(cr, uid, 'auth_signup.template_user_id', 0) - if user_template_id: - self.pool.get('res.users').copy(cr, SUPERUSER_ID, user_template_id, new_user, context=context) - else: - self.pool.get('res.users').create(cr, SUPERUSER_ID, new_user, context=context) - - def auth_signup(self, cr, uid, name, login, password, context=None): - r = (cr.dbname, login, password) - res = self.search(cr, uid, [("login", "=", login)]) - if res: - # Existing user - user_id = res[0] - try: - self.check(cr.dbname, user_id, password) - # Same password - except openerp.exceptions.AccessDenied: - # Different password - raise - else: - # New user - new_user = { - 'name': name, - 'login': login, - 'user_email': login, - 'password': password, - 'active': True, - } - self.auth_signup_create(cr, uid, new_user) - return r - -# diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js index 2ab13aa7598..bec32ce2803 100644 --- a/addons/auth_signup/static/src/js/auth_signup.js +++ b/addons/auth_signup/static/src/js/auth_signup.js @@ -5,56 +5,68 @@ openerp.auth_signup = function(instance) { instance.web.Login.include({ start: function() { var self = this; - this.$('a.oe_signup').click(function() { - var dbname = self.$("form [name=db]").val(); - self.do_action({ - type: 'ir.actions.client', - tag: 'auth_signup.signup', - params: {'dbname': dbname}, - target: 'new', - name: 'Sign up' - }); - return true; - }); - return this._super(); + var d = this._super(); + // hide the signup fields in the case of a regular login + self.on_change_mode() + self.$("form input[name=signup]").click(self.on_change_mode); + // in case of a signup, retrieve the user information from the token + if (self.params.db && self.params.token) { + d = self.rpc("/auth_signup/retrieve", {dbname: self.params.db, token: self.params.token}) + .done(self.on_token_loaded) + .fail(self.on_token_failed); + } + return d; }, - }); - - - instance.auth_signup.Signup = instance.web.Widget.extend({ - template: 'auth_signup.signup', - init: function(parent, params) { - this.params = params; - return this._super(); + on_token_loaded: function(result) { + // set the name and login of user + this.selected_db = result.db; + this.on_db_loaded({db_list: [result.db]}); + this.$("form input[name=signup]").val(result.login ? [] : ["check_signup"]); + this.$("form input[name=name]").val(result.name); + this.$("form input[name=login]").val(result.login || result.email); + this.$("form input[name=password]").val(""); + this.$("form input[name=confirm_password]").val(""); + this.on_change_mode(); }, - start: function() { - var self = this; - this.$('input[name=password_confirmation]').keyup(function() { - var v = $(this).val(); - var $b = self.$('button'); - if (_.isEmpty(v) || self.$('input[name=password]').val() === v) { - $b.removeAttr('disabled'); + on_token_failed: function(result) { + // currently does nothing + }, + on_change_mode: function() { + // 'mode' has changed: regular login, sign up, reset password + var is_signup = this.$("input[name=signup]:checked").val(); + this.$(".oe_signup").toggleClass('oe_form_invisible', false && !is_signup); + return true; + }, + on_submit: function(ev) { + if (ev) { + ev.preventDefault(); + } + if (this.params.token || this.$("input[name=signup]:checked").val()) { + // signup user (or reset password) + var db = this.params.db; + var name = this.$("form input[name=name]").val(); + var login = this.$("form input[name=login]").val(); + var password = this.$("form input[name=password]").val(); + var confirm_password = this.$("form input[name=confirm_password]").val(); + + if (password && password === confirm_password) { + var params = { + dbname : db, + token: this.params.token, + name: name, + login: login, + password: password, + }; + var url = "/auth_signup/signup?" + $.param(params); + window.location = url; } else { - $b.attr('disabled', 'disabled'); + alert('Incorrect password; please retype your password.'); } - }); - - this.$('form').submit(function(ev) { - if(ev) { - ev.preventDefault(); - } - var params = { - dbname : self.params.dbname, - name: self.$('input[name=name]').val(), - login: self.$('input[name=email]').val(), - password: self.$('input[name=password]').val(), - }; - var url = "/auth_signup/signup?" + $.param(params); - window.location = url; - }); - return this._super(); - } + } else { + // regular login + this._super(ev); + } + }, }); - instance.web.client_actions.add("auth_signup.signup", "instance.auth_signup.Signup"); }; diff --git a/addons/auth_signup/static/src/xml/auth_signup.xml b/addons/auth_signup/static/src/xml/auth_signup.xml index c2eec846d15..73e26eb6ba8 100644 --- a/addons/auth_signup/static/src/xml/auth_signup.xml +++ b/addons/auth_signup/static/src/xml/auth_signup.xml @@ -1,28 +1,27 @@ - + - - -
                            • - -
                            • + + + + + + + +
                            • Username
                            • +
                              + + + +
                              -
                              - - -
                              -
                              - Name =
                              - Email =
                              - Password =
                              - Confirmation =
                              - -
                              -
                              -
                              - -
                              From 5a6c5044191486310f52e69bb39ec28f2f65b4e7 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 25 Sep 2012 14:01:29 +0200 Subject: [PATCH 291/726] [IMP] Pimp my gimp bzr revid: fme@openerp.com-20120925120129-0wx4451e1bi81dn6 --- addons/auth_oauth/auth_oauth_data.xml | 2 +- addons/auth_oauth/static/src/css/auth_oauth.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/auth_oauth/auth_oauth_data.xml b/addons/auth_oauth/auth_oauth_data.xml index 86b0f6c593e..feb4e5339ad 100644 --- a/addons/auth_oauth/auth_oauth_data.xml +++ b/addons/auth_oauth/auth_oauth_data.xml @@ -3,7 +3,7 @@ - OpenERP + OpenERP Online https://openerp.my.openerp.com/oauth2/auth userinfo https://openerp.my.openerp.com/oauth2/tokeninfo diff --git a/addons/auth_oauth/static/src/css/auth_oauth.css b/addons/auth_oauth/static/src/css/auth_oauth.css index ef0d648e950..8e267e17845 100644 --- a/addons/auth_oauth/static/src/css/auth_oauth.css +++ b/addons/auth_oauth/static/src/css/auth_oauth.css @@ -1,3 +1,7 @@ +.openerp .oe_application .zocial { + font: white; +} + .zocial.openerp:before { content: "\E02E"; font-style: italic; From 597919467d4ecedddb2b3e14798c10bdf020f7ea Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 14:45:57 +0200 Subject: [PATCH 292/726] [IMP] auth_signup: add css bzr revid: rco@openerp.com-20120925124557-2yka4yu0x7528atl --- addons/auth_signup/__openerp__.py | 1 + addons/auth_signup/static/src/css/Makefile | 3 +++ addons/auth_signup/static/src/css/base.css | 4 ++++ addons/auth_signup/static/src/css/base.sass | 7 +++++++ 4 files changed, 15 insertions(+) create mode 100644 addons/auth_signup/static/src/css/Makefile create mode 100644 addons/auth_signup/static/src/css/base.css create mode 100644 addons/auth_signup/static/src/css/base.sass diff --git a/addons/auth_signup/__openerp__.py b/addons/auth_signup/__openerp__.py index 9cfe89cdc1c..5bb3aab4ec0 100644 --- a/addons/auth_signup/__openerp__.py +++ b/addons/auth_signup/__openerp__.py @@ -36,5 +36,6 @@ Allow users to sign up. 'res_config.xml', ], 'js': ['static/src/js/auth_signup.js'], + 'css' : ['static/src/css/base.css'], 'qweb': ['static/src/xml/auth_signup.xml'], } diff --git a/addons/auth_signup/static/src/css/Makefile b/addons/auth_signup/static/src/css/Makefile new file mode 100644 index 00000000000..d6b4f4b2fc8 --- /dev/null +++ b/addons/auth_signup/static/src/css/Makefile @@ -0,0 +1,3 @@ +base.css: base.sass + sass --trace -t expanded base.sass base.css + diff --git a/addons/auth_signup/static/src/css/base.css b/addons/auth_signup/static/src/css/base.css new file mode 100644 index 00000000000..153f27bd129 --- /dev/null +++ b/addons/auth_signup/static/src/css/base.css @@ -0,0 +1,4 @@ +@charset "utf-8"; +.openerp .oe_login input[type="checkbox"] { + width: 21px !important; +} diff --git a/addons/auth_signup/static/src/css/base.sass b/addons/auth_signup/static/src/css/base.sass new file mode 100644 index 00000000000..87bdb623727 --- /dev/null +++ b/addons/auth_signup/static/src/css/base.sass @@ -0,0 +1,7 @@ +@charset "utf-8" + +.openerp + // Login form + .oe_login + input[type="checkbox"] + width: 21px !important From 3120f9e0485a180ba08ed9e364d3698c00580f0b Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 25 Sep 2012 14:51:25 +0200 Subject: [PATCH 293/726] [FIX] redirect should use hash instead of url params bzr revid: fme@openerp.com-20120925125125-58j0z3g3evbvi7bc --- addons/auth_oauth_provider/static/src/js/oauth_provider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/auth_oauth_provider/static/src/js/oauth_provider.js b/addons/auth_oauth_provider/static/src/js/oauth_provider.js index b81b824cd88..84a89415ed3 100644 --- a/addons/auth_oauth_provider/static/src/js/oauth_provider.js +++ b/addons/auth_oauth_provider/static/src/js/oauth_provider.js @@ -56,7 +56,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ if (params.state) { new_params.state = params.state; } - var redirect = a.protocol + '//' + a.host + a.pathname + '?' + $.param(new_params) + a.hash; + var redirect = params.redirect_uri + (a.hash ? '&' : '#') + $.param(new_params); window.location = redirect; }, error: function(msg) { From e184913f346f891fd74c2c6f1e0f048beb283fbb Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 14:55:22 +0200 Subject: [PATCH 294/726] [FIX] auth_signup: store and retrieve config parameters that may be null bzr revid: rco@openerp.com-20120925125522-2t74fta15yfoesc1 --- addons/auth_signup/res_config.py | 11 +++++++---- addons/auth_signup/res_users.py | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/addons/auth_signup/res_config.py b/addons/auth_signup/res_config.py index 36732d439f5..c69c01127f6 100644 --- a/addons/auth_signup/res_config.py +++ b/addons/auth_signup/res_config.py @@ -20,6 +20,7 @@ ############################################################################## from openerp.osv import osv, fields +from openerp.tools.safe_eval import safe_eval class base_config_settings(osv.TransientModel): _inherit = 'base.config.settings' @@ -31,13 +32,15 @@ class base_config_settings(osv.TransientModel): def get_default_auth_signup_template_user_id(self, cr, uid, fields, context=None): icp = self.pool.get('ir.config_parameter') + # we use safe_eval on the result, since the value of the parameter is a nonempty string return { - 'auth_signup_uninvited': icp.get_param(cr, uid, 'auth_signup.allow_uninvited', False), - 'auth_signup_template_user_id': icp.get_param(cr, uid, 'auth_signup.template_user_id', False), + 'auth_signup_uninvited': safe_eval(icp.get_param(cr, uid, 'auth_signup.allow_uninvited', 'False')), + 'auth_signup_template_user_id': safe_eval(icp.get_param(cr, uid, 'auth_signup.template_user_id', 'False')), } def set_auth_signup_template_user_id(self, cr, uid, ids, context=None): config = self.browse(cr, uid, ids[0], context=context) icp = self.pool.get('ir.config_parameter') - icp.set_param(cr, uid, 'auth_signup.allow_uninvited', config.auth_signup_uninvited) - icp.set_param(cr, uid, 'auth_signup.template_user_id', config.auth_signup_template_user_id.id) + # we store the repr of the values, since the value of the parameter is a required string + icp.set_param(cr, uid, 'auth_signup.allow_uninvited', repr(config.auth_signup_uninvited)) + icp.set_param(cr, uid, 'auth_signup.template_user_id', repr(config.auth_signup_template_user_id.id)) diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py index 600ed9c000e..6956c8e2109 100644 --- a/addons/auth_signup/res_users.py +++ b/addons/auth_signup/res_users.py @@ -23,6 +23,7 @@ import openerp from openerp.osv import osv, fields from openerp import SUPERUSER_ID from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT +from openerp.tools.safe_eval import safe_eval import time import random @@ -152,10 +153,11 @@ class res_users(osv.Model): """ create a new user from the template user """ # check that uninvited users may sign up ir_config_parameter = self.pool.get('ir.config_parameter') - if token and not ir_config_parameter.get_param(cr, uid, 'auth_signup.allow_uninvited', False): - raise Exception('Signup is not allowed for uninvited users') + if not token: + if not safe_eval(ir_config_parameter.get_param(cr, uid, 'auth_signup.allow_uninvited', 'False')): + raise Exception('Signup is not allowed for uninvited users') - template_user_id = ir_config_parameter.get_param(cr, uid, 'auth_signup.template_user_id') + template_user_id = safe_eval(ir_config_parameter.get_param(cr, uid, 'auth_signup.template_user_id', 'False')) assert template_user_id, 'Signup: missing template user' values.update({'active': True, 'signup_token': False, 'signup_expiration': False}) return self.copy(cr, uid, template_user_id, values, context=context) From d5c69fa87e9d17c92c00347af73fce53fb47dcd4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 15:59:55 +0200 Subject: [PATCH 295/726] [FIX] use lists instead of iterators in BaseModel._extract_records * although it does use an explicit external index, it turns out the code is less complex * the rewrapping of (many) iterators on top of one another ended up blowing Python's stack during ``next`` calls, which Python does *not* like * added a 900-ish import test file to check for these things bzr revid: xmo@openerp.com-20120925135955-oielhopegnefyctm --- openerp/addons/base/ir/ir_fields.py | 5 +- openerp/osv/orm.py | 53 +++++-------------- .../addons/test_impex/tests/test_load.py | 13 +++++ 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index cec74e8976e..03d95fc67a6 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -69,7 +69,7 @@ class ir_fields_converter(orm.Model): """ # FIXME: return None converter = getattr( - self, '_%s_to_%s' % (fromtype.__name__, column._type)) + self, '_%s_to_%s' % (fromtype.__name__, column._type), None) if not converter: return None return functools.partial( @@ -113,6 +113,9 @@ class ir_fields_converter(orm.Model): def _str_to_text(self, cr, uid, model, column, value, context=None): return value or False + def _str_to_binary(self, cr, uid, model, column, value, context=None): + return value or False + def _get_translations(self, cr, uid, types, src, context): types = tuple(types) # Cache translations so they don't have to be reloaded from scratch on diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 25974760bdd..eb7745b2f6e 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1527,7 +1527,7 @@ class BaseModel(object): return {'ids': ids, 'messages': messages} def _extract_records(self, cr, uid, fields_, data, context=None, log=lambda a: None): - """ Generates record dicts from the data iterable. + """ Generates record dicts from the data sequence. The result is a generator of dicts mapping field names to raw (unconverted, unvalidated) values. @@ -1562,12 +1562,11 @@ class BaseModel(object): def only_o2m_values(row, f=get_nono2m_values, g=get_o2m_values): return any(g(row)) and not any(f(row)) - rows = CountingStream(data) + index = 0 while True: - row = next(rows, None) - if row is None: return - record_row_index = rows.index + if index >= len(data): return + row = data[index] # copy non-relational fields to record dict record = dict((field[0], value) for field, value in itertools.izip(fields_, row) @@ -1575,10 +1574,10 @@ class BaseModel(object): # Get all following rows which have relational values attached to # the current record (no non-relational values) - # WARNING: replaces existing ``rows`` - record_span, _rows = span(only_o2m_values, rows) + record_span = itertools.takewhile( + only_o2m_values, itertools.islice(data, index + 1, None)) # stitch record row back on for relational fields - record_span = itertools.chain([row], record_span) + record_span = list(itertools.chain([row], record_span)) for relfield in set( field[0] for field in fields_ if is_relational(field[0])): @@ -1586,8 +1585,6 @@ class BaseModel(object): # FIXME: how to not use _obj without relying on fields_get? Model = self.pool[column._obj] - # copy stream to reuse for next relational field - fieldrows, record_span = itertools.tee(record_span) # get only cells for this sub-field, should be strictly # non-empty, field path [None] is for name_get column indices, subfields = zip(*((index, field[1:] or [None]) @@ -1596,26 +1593,17 @@ class BaseModel(object): # return all rows which have at least one value for the # subfields of relfield - relfield_data = filter(any, map(itemgetter_tuple(indices), fieldrows)) + relfield_data = filter(any, map(itemgetter_tuple(indices), record_span)) record[relfield] = [subrecord for subrecord, _subinfo in Model._extract_records( cr, uid, subfields, relfield_data, context=context, log=log)] - # Ensure full consumption of the span (and therefore advancement of - # ``rows``) even if there are no relational fields. Needs two as - # the code above stiched the row back on (so first call may only - # get the stiched row without advancing the underlying operator row - # itself) - next(record_span, None) - next(record_span, None) - # old rows consumption (by iterating the span) should be done here, - # at this point the old ``rows`` is 1 past `span` (either on the - # next record row or past ``StopIteration``, so wrap new ``rows`` - # (``_rows``) in a counting stream indexed 1-before the old - # ``rows`` - rows = CountingStream(_rows, rows.index - 1) - yield record, {'rows': {'from': record_row_index,'to': rows.index}} + yield record, {'rows': { + 'from': index, + 'to': index + len(record_span) - 1 + }} + index += len(record_span) def _convert_records(self, cr, uid, records, context=None, log=lambda a: None): """ Converts records from the source iterable (recursive dicts of @@ -5369,21 +5357,6 @@ class AbstractModel(BaseModel): _auto = False # don't create any database backend for AbstractModels _register = False # not visible in ORM registry, meant to be python-inherited only -def span(predicate, iterable): - """ Splits the iterable between the longest prefix of ``iterable`` whose - elements satisfy ``predicate`` and the rest. - - If called with a list, equivalent to:: - - takewhile(predicate, lst), dropwhile(predicate, lst) - - :param callable predicate: - :param iterable: - :rtype: (iterable, iterable) - """ - it1, it2 = itertools.tee(iterable) - return (itertools.takewhile(predicate, it1), - itertools.dropwhile(predicate, it2)) def itemgetter_tuple(items): """ Fixes itemgetter inconsistency (useful in some cases) of not returning a tuple if len(items) == 1: always returns an n-tuple where n = len(items) diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index eb777a57988..72442963af5 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +import json +import pkgutil + import openerp.modules.registry import openerp @@ -956,5 +959,15 @@ class test_o2m_multiple(ImporterCase): self.assertEqual(values(b.child1), [11, 12, 13, 14]) self.assertEqual(values(b.child2), [21, 22, 23]) +class test_realworld(common.TransactionCase): + def test_bigfile(self): + data = json.loads(pkgutil.get_data(self.__module__, 'contacts_big.json')) + result = self.registry('res.partner').load( + self.cr, openerp.SUPERUSER_ID, + ['name', 'mobile', 'email', 'image'], + data) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), len(data)) + # function, related, reference: written to db as-is... # => function uses @type for value coercion/conversion From 9906a2bda10ca089fff55521f3252f4f8b178344 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 25 Sep 2012 16:34:33 +0200 Subject: [PATCH 296/726] [IMP] auth_signup: improve error message handling in web client bzr revid: rco@openerp.com-20120925143433-p4r2gl6t37dw0s17 --- addons/auth_signup/controllers/main.py | 8 +-- .../auth_signup/static/src/js/auth_signup.js | 61 ++++++++++++++----- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 343c660ff7d..6e053715c09 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -55,14 +55,10 @@ class Controller(openerpweb.Controller): credentials = res_users.signup(cr, SUPERUSER_ID, values, token) cr.commit() return login_and_redirect(req, *credentials) - except AttributeError: - # auth_signup is not installed - _logger.exception('attribute error when signup') - url = "/#action=auth_signup&error=NA" # Not Available - except Exception: + except Exception as e: # signup error _logger.exception('error when signup') - url = "/#action=auth_signup&error=UE" # Unexcpected Error + url = "/#action=login&error_message=%s" % werkzeug.urls.url_quote(e.message) return werkzeug.utils.redirect(url) # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js index bec32ce2803..9c90358d9e3 100644 --- a/addons/auth_signup/static/src/js/auth_signup.js +++ b/addons/auth_signup/static/src/js/auth_signup.js @@ -6,9 +6,21 @@ openerp.auth_signup = function(instance) { start: function() { var self = this; var d = this._super(); + // hide the signup fields in the case of a regular login self.on_change_mode() self.$("form input[name=signup]").click(self.on_change_mode); + + // if there is an error message, show it then forget it + if (self.params.error_message) { + this.$el.addClass('oe_login_invalid'); + this.$(".oe_login_error_message").text(self.params.error_message); + delete self.params.error_message; + } else { + this.$el.removeClass('oe_login_invalid'); + this.$(".oe_login_error_message").text("Invalid username or password"); + } + // in case of a signup, retrieve the user information from the token if (self.params.db && self.params.token) { d = self.rpc("/auth_signup/retrieve", {dbname: self.params.db, token: self.params.token}) @@ -28,8 +40,14 @@ openerp.auth_signup = function(instance) { this.$("form input[name=confirm_password]").val(""); this.on_change_mode(); }, - on_token_failed: function(result) { - // currently does nothing + on_token_failed: function(result, ev) { + if (ev) { + ev.preventDefault(); + } + this.$el.addClass('oe_login_invalid'); + this.$(".oe_login_error_message").text("Invalid signup token"); + delete this.params.db; + delete this.params.token; }, on_change_mode: function() { // 'mode' has changed: regular login, sign up, reset password @@ -43,25 +61,36 @@ openerp.auth_signup = function(instance) { } if (this.params.token || this.$("input[name=signup]:checked").val()) { // signup user (or reset password) - var db = this.params.db; + var db = this.$("form [name=db]").val(); var name = this.$("form input[name=name]").val(); var login = this.$("form input[name=login]").val(); var password = this.$("form input[name=password]").val(); var confirm_password = this.$("form input[name=confirm_password]").val(); - - if (password && password === confirm_password) { - var params = { - dbname : db, - token: this.params.token, - name: name, - login: login, - password: password, - }; - var url = "/auth_signup/signup?" + $.param(params); - window.location = url; - } else { - alert('Incorrect password; please retype your password.'); + if (!db) { + this.do_warn("Login", "No database selected !"); + return false; + } else if (!name) { + this.do_warn("Login", "Please enter a name.") + return false; + } else if (!login) { + this.do_warn("Login", "Please enter a username.") + return false; + } else if (!password || !confirm_password) { + this.do_warn("Login", "Please enter a password and confirm it.") + return false; + } else if (password !== confirm_password) { + this.do_warn("Login", "Passwords do not match; please retype them.") + return false; } + var params = { + dbname : db, + token: this.params.token || "", + name: name, + login: login, + password: password, + }; + var url = "/auth_signup/signup?" + $.param(params); + window.location = url; } else { // regular login this._super(ev); From e61dc509341ed2cd1222869048a81b2db209e21d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 25 Sep 2012 17:59:15 +0200 Subject: [PATCH 297/726] [IMP] convert empty import fields to False values without going through converters simplifies the converter methods by avoiding redundant emptiness checks bzr revid: xmo@openerp.com-20120925155915-82p2s6stpww37p5n --- openerp/addons/base/ir/ir_fields.py | 8 +++----- openerp/osv/orm.py | 4 +++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 03d95fc67a6..621dd93d469 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -100,21 +100,19 @@ class ir_fields_converter(orm.Model): return True def _str_to_integer(self, cr, uid, model, column, value, context=None): - if not value: return False return int(value) def _str_to_float(self, cr, uid, model, column, value, context=None): - if not value: return False return float(value) def _str_to_char(self, cr, uid, model, column, value, context=None): - return value or False + return value def _str_to_text(self, cr, uid, model, column, value, context=None): - return value or False + return value def _str_to_binary(self, cr, uid, model, column, value, context=None): - return value or False + return value def _get_translations(self, cr, uid, types, src, context): types = tuple(types) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index eb7745b2f6e..81063deb180 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -68,7 +68,6 @@ from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ from openerp import SUPERUSER_ID from query import Query -from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) _schema = logging.getLogger(__name__ + '.schema') @@ -1662,6 +1661,9 @@ class BaseModel(object): for field, strvalue in record.iteritems(): if field in (None, 'id', '.id'): continue + if not strvalue: + converted[field] = False + continue # In warnings and error messages, use translated string as # field name From a912bb31890a9d1d81f8b267e2ba2e0d0ca53dbe Mon Sep 17 00:00:00 2001 From: Saurang Suthar Date: Wed, 26 Sep 2012 12:33:39 +0530 Subject: [PATCH 298/726] [IMP]openerp:rename the group Partner Manager -> Contact Creation bzr revid: ssu@tinyerp.com-20120926070339-sr9lv02l5632ml1t --- openerp/addons/base/res/res_security.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_security.xml b/openerp/addons/base/res/res_security.xml index acec903c1a3..783243411ef 100644 --- a/openerp/addons/base/res/res_security.xml +++ b/openerp/addons/base/res/res_security.xml @@ -3,7 +3,7 @@ - Partner Manager + Contact Creation From 4ddb50dbf920a02bbb6f1c210a1215abd8a0b428 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 26 Sep 2012 09:17:09 +0200 Subject: [PATCH 299/726] [IMP] mail: subtype adapted for css onhover box bzr revid: chm@openerp.com-20120926071709-v51ra4mzn2hp121j --- addons/mail/mail_message.py | 2 + addons/mail/mail_thread.py | 15 ++-- addons/mail/static/src/css/mail.css | 44 ++++++--- addons/mail/static/src/js/mail.js | 90 +++++++++++++------ addons/mail/static/src/js/mail_followers.js | 89 +++++++++--------- addons/mail/static/src/xml/mail.xml | 13 +-- addons/mail/static/src/xml/mail_followers.xml | 16 ++-- 7 files changed, 165 insertions(+), 104 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index fc830a3c214..08834686088 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -201,6 +201,7 @@ class mail_message(osv.Model): partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context) except (orm.except_orm, osv.except_osv): partner_ids = [] + return { 'id': msg.id, 'type': msg.type, @@ -216,6 +217,7 @@ class mail_message(osv.Model): 'partner_ids': partner_ids, 'child_ids': [], 'child_nbr': child_nbr, + 'parent_id': msg.parent_id and msg.parent_id.id or False, 'vote_user_ids': vote_ids, 'has_voted': has_voted } diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 665ca664994..f004dd9a900 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -625,11 +625,6 @@ class mail_thread(osv.AbstractModel): ``(name,content)``, where content is NOT base64 encoded :return: ID of newly created mail.message """ - # message_post - # [26] False notification mt_crm_stage False - - # message_post - # [26] False notification mt_crm_won False context = context or {} attachments = attachments or [] @@ -653,6 +648,7 @@ class mail_thread(osv.AbstractModel): } attachment_ids.append((0, 0, data_attach)) + # get subtype if subtype: ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', subtype) subtype_id = ref and ref[1] or False @@ -684,11 +680,10 @@ class mail_thread(osv.AbstractModel): for x in ('from', 'to', 'cc'): values.pop(x, None) - print "------------------------------------------" - print values, "mail_thread 688" - print "--------≃============----------------------------------" - - return messages.create(cr, uid, values, context=context) + added_message_id = messages.create(cr, uid, values, context=context) + added_message = self.pool.get('mail.message').message_read(cr, uid, [added_message_id]) + + return added_message #------------------------------------------------------ # Followers API diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 3fde4cbc67b..497e5940791 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -50,14 +50,6 @@ .openerp div.oe_mail_recthread_aside input { cursor:pointer; } -.openerp div.oe_mail_recthread_subtypes { - display:none; -} -.openerp div.oe_mail_recthread_aside button span { - position: absolute; - top:-7px; - right:5px; -} /* Specific display of threads in the wall */ /* ------------------------------------------------------------ */ @@ -108,7 +100,7 @@ width: 120px; } -.openerp button.oe_mail_button_mouseout { +.openerp .oe_mail_recthread_aside .oe_follower.oe_follow { color: white; background-color: #8a89ba; background-image: -webkit-gradient(linear, left top, left bottom, from(#8a89ba), to(#807fb4)); @@ -118,9 +110,7 @@ background-image: -o-linear-gradient(top, #8a89ba, #807fb4); background-image: linear-gradient(to bottom, #8a89ba, #807fb4); } - -.openerp button.oe_mail_button_mouseover { - display: none; +.openerp .oe_mail_recthread_aside .oe_follower.oe_following { color: white; background-color: #dc5f59; background-image: -webkit-gradient(linear, left top, left bottom, from(#dc5f59), to(#b33630)); @@ -131,10 +121,40 @@ background-image: linear-gradient(to bottom, #dc5f59, #b33630); } + +.openerp .oe_mail_recthread_aside .oe_follower span { + display:none; +} +.openerp .oe_mail_recthread_aside .oe_following span.oe_following, +.openerp .oe_mail_recthread_aside .oe_notfollow span.oe_follow { + display:block; +} + .openerp div.oe_mail_recthread_followers { margin-bottom: 8px; } + +/* ------------------------------------------------------------ */ +/* subtypes +/* ------------------------------------------------------------ */ + +.openerp .oe_mouse_subtypes { + display:inline-block; + position: relative; + z-index: 5; +} +.openerp .oe_mouse_subtypes .oe_recthread_subtypes { + position: absolute; + z-index: 2; +} +.openerp .oe_mouse_subtypes.oe_mouseout .oe_recthread_subtypes { + display: none; +} +.openerp .oe_mouse_subtypes.oe_mouseover .oe_recthread_subtypes { + display: block; +} + /* ------------------------------------------------------------ */ /* Thread /* ------------------------------------------------------------ */ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 8adba39507c..f4ae9018df1 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -110,8 +110,8 @@ openerp.mail = function(session) { this._super.apply(this, arguments); // customize display: add avatar, clean previous content var user_avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); - this.$el.find('img.oe_mail_icon').attr('src', user_avatar); - this.$el.find('div.oe_mail_msg_content').empty(); + this.$('img.oe_mail_icon').attr('src', user_avatar); + this.$('div.oe_mail_msg_content').empty(); // create a context for the dataset and default_get of the wizard var context = _.extend({}, this.options.context); this.ds_compose = new session.web.DataSetSearch(this, 'mail.compose.message', context); @@ -139,21 +139,21 @@ openerp.mail = function(session) { disable_autofocus: true, }); // add the form, bind events, activate the form - var msg_node = this.$el.find('div.oe_mail_msg_content'); + var msg_node = this.$('div.oe_mail_msg_content'); return $.when(this.form_view.appendTo(msg_node)).pipe(this.proxy('postprocess_create_form_view')); }, postprocess_create_form_view: function () { // handle attachment button this.fileupload_id = _.uniqueId('oe_fileupload'); - var button_attach = this.$el.find('button.oe_mail_compose_message_attachment'); + var button_attach = this.$('button.oe_mail_compose_message_attachment'); var rendered = session.web.qweb.render('mail.compose_message.add_attachment', {'widget': this}); $(rendered).insertBefore(button_attach); // move the button inside div.oe_hidden_input_file - var input_node = this.$el.find('input[name=ufile]'); + var input_node = this.$('input[name=ufile]'); button_attach.detach().insertAfter(input_node); // set the function called when attachments are added - this.$el.find('input.oe_form_binary_file').change(this.on_attachment_change); + this.$('input.oe_form_binary_file').change(this.on_attachment_change); this.bind_events(); this.form_view.do_show(); }, @@ -161,7 +161,7 @@ openerp.mail = function(session) { on_attachment_change: function (event) { var $target = $(event.target); if ($target.val() !== '') { - this.$el.find('form.oe_form_binary_form').submit(); + this.$('form.oe_form_binary_form').submit(); session.web.blockUI(); } }, @@ -178,11 +178,11 @@ openerp.mail = function(session) { }, display_attachments: function () { - var attach_node = this.$el.find('div.oe_mail_compose_message_attachments'); + var attach_node = this.$('div.oe_mail_compose_message_attachments'); var rendered = session.web.qweb.render('mail.thread.message.attachments', {'record': this}); attach_node.empty(); $(rendered).appendTo(attach_node); - this.$el.find('.oe_mail_msg_attachments').show(); + this.$('.oe_mail_msg_attachments').show(); var composer_attachment_ids = _.pluck(this.attachment_ids, 'id'); var onchange_like = {'value': {'attachment_ids': composer_attachment_ids}} this.form_view.on_processed_onchange(onchange_like, []); @@ -283,6 +283,7 @@ openerp.mail = function(session) { show_dd_delete: options.show_dd_delete || false, show_dd_hide: options.show_dd_hide || false, truncate_limit: options.truncate_limit || 250, + mail_wall: options.mail_wall || this } // datasets and internal vars this.records = {}; @@ -309,7 +310,7 @@ openerp.mail = function(session) { * - show_header_compose: show the composition form in the header */ do_customize_display: function() { if (this.options.show_header_compose) { - this.$el.find('div.oe_mail_thread_action').eq(0).show(); + this.$('div.oe_mail_thread_action').eq(0).show(); } }, @@ -321,7 +322,7 @@ openerp.mail = function(session) { // event: click on 'More' at bottom of thread this.$el.on('click', 'a.oe_mail_fetch_more', this.do_message_fetch_more); // event: writing in basic textarea of composition form (quick reply) - this.$el.find('textarea.oe_mail_compose_textarea').keyup(function (event) { + this.$('textarea.oe_mail_compose_textarea').keyup(function (event) { var charCode = (event.which) ? event.which : window.event.keyCode; if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; } else if (charCode == 13) { return self.message_post(); } @@ -405,7 +406,7 @@ openerp.mail = function(session) { this.compose_message_widget = new mail.ComposeMessage(this, { 'context': _.extend(context || {}, this.context), }); - var composition_node = this.$el.find('div.oe_mail_thread_action'); + var composition_node = this.$('div.oe_mail_thread_action'); composition_node.empty(); var compose_done = this.compose_message_widget.appendTo(composition_node); return compose_done; @@ -418,7 +419,7 @@ openerp.mail = function(session) { /** Clean the thread */ message_clean: function() { - this.$el.find('div.oe_mail_thread_display').empty(); + this.$('div.oe_mail_thread_display').empty(); }, /** Fetch messages @@ -467,9 +468,10 @@ openerp.mail = function(session) { 'show_reply': self.options.show_reply && self.options.thread_level > 1, 'show_reply_by_email': self.options.show_reply_by_email, 'show_dd_hide': self.options.show_dd_hide, - 'show_dd_delete': self.options.show_dd_delete }); - self.$el.find('li.oe_mail_thread_msg:last').append('
                              '); - self.thread.appendTo(self.$el.find('div.oe_mail_thread_subthread:last')); + 'show_dd_delete': self.options.show_dd_delete, + 'mail_wall': self.options.mail_wall }); + self.$('li.oe_mail_thread_msg:last').append('
                              '); + self.thread.appendTo(self.$('div.oe_mail_thread_subthread:last')); } }); }, @@ -497,7 +499,7 @@ openerp.mail = function(session) { // render, add the expand feature var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'options': this.options}); $(rendered).appendTo(this.$el.children('div.oe_mail_thread_display:first')); - this.$el.find('div.oe_mail_msg_body').expander({ + this.$('div.oe_mail_msg_body').expander({ slicePoint: this.options.truncate_limit, expandText: 'read more', userCollapseText: '[^]', @@ -526,19 +528,41 @@ openerp.mail = function(session) { display_user_avatar: function () { var avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); - return this.$el.find('img.oe_mail_icon').attr('src', avatar); + return this.$('img.oe_mail_icon').attr('src', avatar); }, + /* Display the message if if the msg_id don't exists. + * If the record have a parent, insert parent or inside parent */ + message_fetch_new_data: function(records) { + var self=this; + + _(records).each(function (record) { + if( !self.options.mail_wall.$('.oe_mail_thread_msg[data-msg_id="'+record.id+'"]').size() ) { + self.display_record( record ); + } + }); + }, + + search_thread: function() { + + }, + + animated_destroy: function(animated) { + //graphic effects + this.destroy(); + }, + + /*post a message and flatch the message*/ message_post: function (body) { var self = this; if (! body) { - var comment_node = this.$el.find('textarea'); + var comment_node = this.$('textarea'); var body = comment_node.val(); comment_node.val(''); } return this.ds_thread.call('message_post', [ - [this.context.default_res_id], body, false, 'comment', this.context.default_parent_id, undefined] - ).pipe(self.message_clean()).pipe(self.message_fetch(false)); + [this.context.default_res_id], body, false, 'comment', false, this.context.default_parent_id, undefined]) + .then(this.proxy('message_fetch_new_data')); }, /** Action: 'shows more' to fetch new messages */ @@ -585,7 +609,7 @@ openerp.mail = function(session) { var self = this; this._super.apply(this, arguments); if (! this.view.datarecord.id || session.web.BufferedDataSet.virtual_id_regex.test(this.view.datarecord.id)) { - this.$el.find('oe_mail_thread').hide(); + this.$('oe_mail_thread').hide(); return; } // update context @@ -597,14 +621,14 @@ openerp.mail = function(session) { // create and render Thread widget var show_header_compose = this.view.is_action_enabled('edit') || (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); - this.$el.find('div.oe_mail_recthread_main').empty(); + this.$('div.oe_mail_recthread_main').empty(); var thread = new mail.Thread(self, domain, this.options.context, { 'thread_level': this.options.thread_level, 'show_header_compose': show_header_compose, 'use_composer': show_header_compose, 'show_dd_delete': true, 'show_reply_by_email': show_header_compose }); - return thread.appendTo(this.$el.find('div.oe_mail_recthread_main')); + return thread.appendTo(this.$('div.oe_mail_recthread_main')); }, }); @@ -656,7 +680,7 @@ openerp.mail = function(session) { load_searchview: function (defaults, hidden) { var self = this; this.searchview = new session.web.SearchView(this, this.ds_msg, false, defaults || {}, hidden || false); - return this.searchview.appendTo(this.$el.find('.oe_view_manager_view_search')).then(function () { + return this.searchview.appendTo(this.$('.oe_view_manager_view_search')).then(function () { self.searchview.on_search.add(self.do_searchview_search); }); }, @@ -681,21 +705,29 @@ openerp.mail = function(session) { return self.message_render(); }); }, + + search_thread: function(id) { + var self=this; + + /*this.thread*/ + }, /** Clean and display the threads */ message_render: function () { - this.$el.find('ul.oe_mail_wall_threads').empty(); + this.$('ul.oe_mail_wall_threads').empty(); var domain = this.options.domain.concat(this.search_results['domain']); var render_res = session.web.qweb.render('mail.wall_thread_container', {}); - $(render_res).appendTo(this.$el.find('ul.oe_mail_wall_threads')); - var thread = new mail.Thread(this, domain, this.options.context, + $(render_res).appendTo(this.$('ul.oe_mail_wall_threads')); + + this.thread = new mail.Thread(this, domain, this.options.context, { 'thread_level': this.options.thread_level, 'use_composer': true, 'show_reply': this.options.thread_level > 0, 'show_dd_hide': true, + 'mail_wall': self } ); - return thread.appendTo(this.$el.find('li.oe_mail_wall_thread:last')); + return this.thread.appendTo(this.$('li.oe_mail_wall_thread:last')); }, }); }; diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 5836bd94ba1..47bf9f74223 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -51,13 +51,33 @@ openerp_mail_followers = function(session, mail) { bind_events: function() { var self = this; - this.$el.find('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); }) - .mouseover(function () { $(this).removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover').find('p').html('Unfollow');}) - .mouseleave(function () { $(this).removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout').find('p').html('Following'); }); + this.$('div.oe_mouse_subtypes') + .on('mouseover', function () { + $(this).removeClass('oe_mouseout').addClass('oe_mouseover'); + self.display_subtypes(); + }) + .on('mouseleave', function () { + $(this).removeClass('oe_mouseover').addClass('oe_mouseout'); + self.display_subtypes(); + }); - this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); }); - this.$el.on('click', 'ul.oe_mail_subtypes input', function () {self.do_update_subscription(); }) - this.$el.on('click', 'button.oe_mail_button_invite', function(event) { + this.$('button.oe_follower') + .on('click', function () { + if($(this).hasClass('oe_notfollow')) + self.do_follow(); + else + self.do_unfollow(); + }) + .on('mouseover', function () { + $(this).removeClass('oe_mouseout').addClass('oe_mouseover'); + }) + .on('mouseleave', function () { + $(this).removeClass('oe_mouseover').addClass('oe_mouseout'); + }); + + this.$el.on('click', 'ul.oe_subtypes input', function () { self.do_update_subscription(); }) + + this.$el.on('click', 'button.oe_invite', function(event) { action = { type: 'ir.actions.act_window', res_model: 'mail.wizard.invite', @@ -72,9 +92,6 @@ openerp_mail_followers = function(session, mail) { } self.do_action(action, function() { self.read_value(); }); }); - - this.$el.find('button span') - .click(function (e) { self.display_subtypes(); e.stopPropagation(); }) }, read_value: function() { @@ -111,7 +128,7 @@ openerp_mail_followers = function(session, mail) { /* Display generic info about follower, for people not having access to res_partner */ display_generic: function (error, event) { event.preventDefault(); - var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty(); + var node_user_list = this.$('ul.oe_mail_followers_display').empty(); // format content: Followers (You and 0 other) // Followers (3) var content = this.options.title; if (this.message_is_follower) { @@ -120,7 +137,7 @@ openerp_mail_followers = function(session, mail) { else { content += ' (' + this.value.length + ')' } - this.$el.find('div.oe_mail_recthread_followers h4').html(content); + this.$('div.oe_mail_recthread_followers h4').html(content); this.display_buttons(); return $.when(); }, @@ -128,29 +145,29 @@ openerp_mail_followers = function(session, mail) { /** Display the followers, evaluate is_follower directly */ display_followers: function (records) { var self = this; - var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty(); - this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')'); - _(records).each(function (record) { + var node_user_list = this.$('ul.oe_mail_followers_display').empty(); + this.$('div.oe_mail_recthread_followers h4').html(this.options.title + (records.length>=5 ? ' (' + records.length + ')' : '') ); + console.log(records); + for(var i=0; i - + +
                              + + + + + + + diff --git a/addons/base_import/static/lib/javascript-state-machine/state-machine.js b/addons/base_import/static/lib/javascript-state-machine/state-machine.js new file mode 100644 index 00000000000..0d503ee7bdb --- /dev/null +++ b/addons/base_import/static/lib/javascript-state-machine/state-machine.js @@ -0,0 +1,155 @@ +(function (window) { + + StateMachine = { + + //--------------------------------------------------------------------------- + + VERSION: "2.1.0", + + //--------------------------------------------------------------------------- + + Result: { + SUCCEEDED: 1, // the event transitioned successfully from one state to another + NOTRANSITION: 2, // the event was successfull but no state transition was necessary + CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback + ASYNC: 4, // the event is asynchronous and the caller is in control of when the transition occurs + }, + + Error: { + INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state + PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending + INVALID_CALLBACK: 300, // caller provided callback function threw an exception + }, + + WILDCARD: '*', + ASYNC: 'async', + + //--------------------------------------------------------------------------- + + create: function(cfg, target) { + + var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false } + var fsm = target || cfg.target || {}; + var events = cfg.events || []; + var callbacks = cfg.callbacks || {}; + var map = {}; + + var add = function(e) { + var from = (e.from instanceof Array) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified + map[e.name] = map[e.name] || {}; + for (var n = 0 ; n < from.length ; n++) + map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified + }; + + if (initial) { + initial.event = initial.event || 'startup'; + add({ name: initial.event, from: 'none', to: initial.state }); + } + + for(var n = 0 ; n < events.length ; n++) + add(events[n]); + + for(var name in map) { + if (map.hasOwnProperty(name)) + fsm[name] = StateMachine.buildEvent(name, map[name]); + } + + for(var name in callbacks) { + if (callbacks.hasOwnProperty(name)) + fsm[name] = callbacks[name] + } + + fsm.current = 'none'; + fsm.is = function(state) { return this.current == state; }; + fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } + fsm.cannot = function(event) { return !this.can(event); }; + fsm.error = cfg.error || function(name, from, to, args, error, msg) { throw msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3) + + if (initial && !initial.defer) + fsm[initial.event](); + + return fsm; + + }, + + //=========================================================================== + + doCallback: function(fsm, func, name, from, to, args) { + if (func) { + try { + return func.apply(fsm, [name, from, to].concat(args)); + } + catch(e) { + return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function"); + } + } + }, + + beforeEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); }, + afterEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); }, + leaveState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); }, + enterState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); }, + changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); }, + + + buildEvent: function(name, map) { + return function() { + + var from = this.current; + var to = map[from] || map[StateMachine.WILDCARD] || from; + var args = Array.prototype.slice.call(arguments); // turn arguments into pure array + + if (this.transition) + return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete"); + + if (this.cannot(name)) + return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current); + + if (false === StateMachine.beforeEvent(this, name, from, to, args)) + return StateMachine.CANCELLED; + + if (from === to) { + StateMachine.afterEvent(this, name, from, to, args); + return StateMachine.NOTRANSITION; + } + + // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState) + var fsm = this; + this.transition = function() { + fsm.transition = null; // this method should only ever be called once + fsm.current = to; + StateMachine.enterState( fsm, name, from, to, args); + StateMachine.changeState(fsm, name, from, to, args); + StateMachine.afterEvent( fsm, name, from, to, args); + }; + + var leave = StateMachine.leaveState(this, name, from, to, args); + if (false === leave) { + this.transition = null; + return StateMachine.CANCELLED; + } + else if ("async" === leave) { + return StateMachine.ASYNC; + } + else { + if (this.transition) + this.transition(); // in case user manually called transition() but forgot to return ASYNC + return StateMachine.SUCCEEDED; + } + + }; + } + + }; // StateMachine + + //=========================================================================== + + if ("function" === typeof define) { + define("statemachine", [], function() { return StateMachine; }); + } + else { + window.StateMachine = StateMachine; + } + +}(this)); + diff --git a/addons/base_import/static/src/js/import.js b/addons/base_import/static/src/js/import.js index 4135f303513..19d4e466cc7 100644 --- a/addons/base_import/static/src/js/import.js +++ b/addons/base_import/static/src/js/import.js @@ -71,14 +71,8 @@ openerp.base_import = function (instance) { ], events: { // 'change .oe_import_grid input': 'import_dryrun', - 'change input.oe_import_file': 'file_update', - 'change input.oe_import_has_header, .oe_import_options input': 'settings_updated', - 'click a.oe_import_csv': function (e) { - e.preventDefault(); - }, - 'click a.oe_import_export': function (e) { - e.preventDefault(); - }, + 'change input.oe_import_file': 'loaded_file', + 'change input.oe_import_has_header, .oe_import_options input': 'settings_changed', 'click a.oe_import_toggle': function (e) { e.preventDefault(); var $el = $(e.target); @@ -109,14 +103,15 @@ openerp.base_import = function (instance) { this.do_action(_.extend(action, {target: 'new'})); }, // buttons - 'click .oe_import_validate': 'import_dryrun', - 'click .oe_import_import': 'do_import', + 'click .oe_import_validate': 'validate', + 'click .oe_import_import': 'import', 'click .oe_import_cancel': function (e) { e.preventDefault(); this.exit(); } }, init: function (parent, params) { + var self = this; this._super.apply(this, arguments); this.res_model = params.model; // import object id @@ -150,42 +145,48 @@ openerp.base_import = function (instance) { }, //- File & settings change section - file_update: function (e) { + onfile_loaded: function () { this.$('.oe_import_button').prop('disabled', true); if (!this.$('input.oe_import_file').val()) { return; } this.$el.removeClass('oe_import_preview oe_import_error'); jsonp(this.$el, { url: '/base_import/set_file' - }, this.proxy('settings_updated')); + }, this.proxy('settings_changed')); }, - settings_updated: function () { + onpreviewing: function () { + var self = this; + this.$('.oe_import_button').prop('disabled', true); this.$el.addClass('oe_import_with_file'); // TODO: test that write // succeeded? - this.Import.call( - 'parse_preview', [this.id, this.import_options()]) - .then(this.proxy('preview')); - }, - preview: function (result) { this.$el.removeClass('oe_import_preview_error oe_import_error'); this.$el.toggleClass( 'oe_import_noheaders', !this.$('input.oe_import_has_header').prop('checked')); - if (result.error) { - this.$('.oe_import_options').show(); - this.$el.addClass('oe_import_preview_error oe_import_error'); - this.$('.oe_import_error_report').html( - QWeb.render('ImportView.preview.error', result)) - .get(0).scrollIntoView(); - return; - } + this.Import.call( + 'parse_preview', [this.id, this.import_options()]) + .then(function (result) { + var signal = result.error ? 'preview_failed' : 'preview_succeeded'; + self[signal](result); + }); + }, + onpreview_error: function (event, from, to, result) { + this.$('.oe_import_options').show(); + this.$el.addClass('oe_import_preview_error oe_import_error'); + this.$('.oe_import_error_report').html( + QWeb.render('ImportView.preview.error', result)) + .get(0).scrollIntoView(); + }, + onpreview_success: function (event, from, to, result) { + this.$('.oe_import_import').removeClass('oe_highlight'); + this.$('.oe_import_validate').addClass('oe_highlight'); this.$('.oe_import_button').prop('disabled', false); this.$el.addClass('oe_import_preview'); this.$('table').html(QWeb.render('ImportView.preview', result)); if (result.headers.length === 1) { this.$('.oe_import_options').show(); - this.render_import_result([{ + this.onresults(null, null, null, [{ type: 'warning', message: _t("A single column was found in the file, this often means the file separator is incorrect") }]); @@ -225,7 +226,6 @@ openerp.base_import = function (instance) { width: 'resolve', dropdownCssClass: 'oe_import_selector' }); - //this.import_dryrun(); }, generate_fields_completion: function (root) { var basic = []; @@ -303,28 +303,31 @@ openerp.base_import = function (instance) { return this.Import.call( 'do', [this.id, fields, this.import_options()], options); }, - import_dryrun: function () { + onvalidate: function () { return this.call_import({ dryrun: true }) - .then(this.proxy('render_import_result')); + .then(this.proxy('validated')); }, - do_import: function () { + onimport: function () { var self = this; return this.call_import({ dryrun: false }).then(function (message) { if (!_.any(message, function (message) { return message.type === 'error' })) { - self.exit(); + self['import_succeeded'](); return; } - self.render_import_result(message); + self['import_failed'](message); }); }, + onimported: function () { + this.exit(); + }, exit: function () { this.do_action({ type: 'ir.actions.client', tag: 'history_back' }); }, - render_import_result: function (message) { + onresults: function (event, from, to, message) { var no_messages = _.isEmpty(message); this.$('.oe_import_import').toggleClass('oe_highlight', no_messages); this.$('.oe_import_validate').toggleClass('oe_highlight', !no_messages); @@ -386,4 +389,23 @@ openerp.base_import = function (instance) { })).get(0).scrollIntoView(); }, }); + // FSM-ize DataImport + StateMachine.create({ + target: instance.web.DataImport.prototype, + events: [ + { name: 'loaded_file', + from: ['none', 'file_loaded', 'preview_error', 'preview_success', 'results'], + to: 'file_loaded' }, + { name: 'settings_changed', + from: ['file_loaded', 'preview_error', 'preview_success', 'results'], + to: 'previewing' }, + { name: 'preview_failed', from: 'previewing', to: 'preview_error' }, + { name: 'preview_succeeded', from: 'previewing', to: 'preview_success' }, + { name: 'validate', from: 'preview_success', to: 'validating' }, + { name: 'validated', from: 'validating', to: 'results' }, + { name: 'import', from: ['preview_success', 'results'], to: 'importing' }, + { name: 'import_succeeded', from: 'importing', to: 'imported'}, + { name: 'import_failed', from: 'importing', to: 'results' } + ] + }) }; From a09b2fdff1586b7cc51053eabc5b3b9f6cc9a8bc Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 3 Oct 2012 17:21:21 +0200 Subject: [PATCH 520/726] [REM] cleanup leftover debug logging bzr revid: odo@openerp.com-20121003152121-yeg4vhph4cy7xgpp --- addons/web/controllers/main.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 7e7282eb231..356e2960346 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -709,7 +709,6 @@ class WebClient(openerpweb.Controller): # Regional languages (ll_CC) must inherit/override their parent lang (ll), but this is # done server-side when the language is loaded, so we only need to load the user's lang. - start = datetime.datetime.now() ir_translation = req.session.model('ir.translation') translations_per_module = {} messages = ir_translation.search_read([('module','in',mods),('lang','=',lang), @@ -721,11 +720,6 @@ class WebClient(openerpweb.Controller): translations_per_module[mod]['messages'].extend({'id': m['src'], 'string': m['value']} \ for m in msg_group) - - print "Loaded translations in ", datetime.datetime.now()-start - import pprint - pprint.pprint(translations_per_module) - return {"modules": translations_per_module, "lang_parameters": lang_params} From 9c9d9781093cf35bb5abec0d605a02bbd9b3f108 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 3 Oct 2012 17:24:44 +0200 Subject: [PATCH 521/726] [IMP] relational field 'more values' dialog list features force display of pager and search view, make list non-selectable bzr revid: xmo@openerp.com-20121003152444-phnn9sc9nqo1ecpn --- addons/base_import/static/src/js/import.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/base_import/static/src/js/import.js b/addons/base_import/static/src/js/import.js index 19d4e466cc7..2867242749c 100644 --- a/addons/base_import/static/src/js/import.js +++ b/addons/base_import/static/src/js/import.js @@ -100,7 +100,15 @@ openerp.base_import = function (instance) { : 'tree' ]; }); - this.do_action(_.extend(action, {target: 'new'})); + this.do_action(_.extend(action, { + target: 'new', + flags: { + search_view: true, + display_title: true, + pager: true, + list: {selectable: false} + } + })); }, // buttons 'click .oe_import_validate': 'validate', From 3744f5c402b05edf50bd4562d0daedbc7cbc08e1 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 3 Oct 2012 17:33:06 +0200 Subject: [PATCH 522/726] [REV] Revert last commit, breaks tests bzr revid: odo@openerp.com-20121003153306-e2ugphdyijvq8x6l --- addons/mail/mail_message.py | 184 ++++++++++++-------- addons/mail/mail_message_view.xml | 11 +- addons/mail/mail_thread.py | 8 +- addons/mail/mail_thread_view.xml | 10 +- addons/mail/static/src/css/mail.css | 2 +- addons/mail/static/src/js/mail.js | 37 ++-- addons/mail/static/src/js/mail_followers.js | 5 +- addons/mail/static/src/xml/mail.xml | 9 +- addons/mail/tests/test_mail.py | 42 +++++ addons/mail/wizard/mail_compose_message.py | 1 + 10 files changed, 195 insertions(+), 114 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index eeefd730f22..bbf68509277 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -134,7 +134,6 @@ class mail_message(osv.Model): 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'), 'vote_user_ids': fields.many2many('res.users', 'mail_vote', 'message_id', 'user_id', string='Votes', help='Users that voted for this message'), - 'is_private': fields.boolean('Private message'), } def _needaction_domain_get(self, cr, uid, context=None): @@ -222,67 +221,70 @@ class mail_message(osv.Model): 'unread': msg.unread and msg.unread['unread'] or False } - def _message_read_expandable(self, cr, uid, tree, result, message_loaded, domain, context, parent_id, limit): - """ - create the expandable message for all parent message read - this function is used by message_read + def message_read_tree_get_expandable(self, cr, uid, parent_message, last_message, domain=[], current_level=0, level=0, context=None): + """ . """ + base_domain = [('id', '<', last_message['id'])] + if parent_message and current_level < level: + base_domain += [('parent_id', '=', parent_message['id'])] + elif parent_message: + base_domain += [('id', 'child_of', parent_message['id']), ('id', '!=', parent_message['id'])] + if domain: + base_domain += domain + extension = { 'type': 'expandable', + 'domain': base_domain, + 'thread_level': current_level, + 'context': context, + 'id': -1, + } + return extension + + def message_read_tree_flatten(self, cr, uid, parent_message, messages, domain=[], level=0, current_level=0, context=None, limit=None, add_expandable=True): + """ Given a tree with several roots of following structure : + [ {'id': 1, 'child_ids': [ + {'id': 11, 'child_ids': [...] },], + {...} ] + Flatten it to have a maximum number of levels, 0 being flat and + sort messages in a level according to a key of the messages. + Perform the flattening at leafs if above the maximum depth, then get + back in the tree. + :param context: ``sort_key``: key for sorting (id by default) + :param context: ``sort_reverse``: reverser order for sorting (True by default) """ + def _flatten(msg_dict): + """ from {'id': x, 'child_ids': [{child1}, {child2}]} + get [{'id': x, 'child_ids': []}, {child1}, {child2}] + """ + child_ids = msg_dict.pop('child_ids', []) + msg_dict['child_ids'] = [] + return [msg_dict] + child_ids - tree_not = [] - # expandable for not show message - for id_msg in tree: - # get all childs - not_loaded_ids = self.search(cr, SUPERUSER_ID, [['parent_id','=',id_msg],['id','not in',message_loaded]], None, limit=1000) - # group childs not read - id_min=None - id_max=None - nb=0 - for not_loaded_id in not_loaded_ids: - if not_loaded_id not in tree: - nb+=1 - if id_min==None or id_min>not_loaded_id: - id_min=not_loaded_id - if id_max==None or id_max0: - result.append({ - 'domain': [['id','>=',id_min],['id','<=',id_max],['parent_id','=',id_msg]], - 'nb_messages': nb, - 'type': 'expandable', - 'parent_id': id_msg, - 'id': id_min - }) - id_min=None - id_max=None - nb=0 - if nb>0: - result.append({ - 'domain': [['id','>=',id_min],['id','<=',id_max],['parent_id','=',id_msg]], - 'nb_messages': nb, - 'type': 'expandable', - 'parent_id': id_msg, - 'id': id_min - }) + context = context or {} + limit = limit or self._message_read_limit + # Depth-first flattening + for message in messages: + if message.get('type') == 'expandable': + continue + message['child_ids'] = self.message_read_tree_flatten(cr, uid, message, message['child_ids'], domain, level, current_level + 1, context=context, limit=limit) + for child in message['child_ids']: + if child.get('type') == 'expandable': + continue + message['child_nbr'] += child['child_nbr'] + # Flatten if above maximum depth + if current_level < level: + return_list = messages + else: + return_list = [flat_message for message in messages for flat_message in _flatten(message)] - # expandable for limit max - ids = self.search(cr, SUPERUSER_ID, domain+[['id','not in',message_loaded+tree+tree_not]], context=context, limit=1) - if len(ids) > 0: - result.append( - { - 'domain': domain, - 'nb_messages': 0, - 'type': 'expandable', - 'parent_id': parent_id, - 'id': -1 - }); - - - result = sorted(result, key=lambda k: k['id']) - - return result + # Add expandable + return_list = sorted(return_list, key=itemgetter(context.get('sort_key', 'id')), reverse=context.get('sort_reverse', True)) + if return_list and current_level == 0 and add_expandable: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, domain, current_level, level, context=context) + return_list.append(expandable) + elif return_list and current_level <= level and add_expandable: + expandable = self.message_read_tree_get_expandable(cr, uid, parent_message, return_list and return_list[-1] or parent_message, domain, current_level, level, context=context) + return_list.append(expandable) + return return_list def message_read(self, cr, uid, ids=False, domain=[], level=0, context=None, parent_id=False, limit=None): """ Read messages from mail.message, and get back a structured tree @@ -298,6 +300,7 @@ class mail_message(osv.Model): further parents :return list: list of trees of messages """ + message_loaded = context and context.get('message_loaded') or [0] # don't read the message display by .js, in context message_loaded list @@ -338,7 +341,58 @@ class mail_message(osv.Model): result = sorted(result, key=lambda k: k['id']) - result = self._message_read_expandable(cr, uid, tree, result, message_loaded, domain, context, parent_id, limit) + + tree_not = [] + # expandable for not show message + for id_msg in tree: + # get all childs + not_loaded_ids = self.search(cr, SUPERUSER_ID, [['parent_id','=',id_msg],['id','not in',message_loaded]], None, limit=1000) + # group childs not read + id_min=None + id_max=None + nb=0 + for not_loaded_id in not_loaded_ids: + if not_loaded_id not in tree: + nb+=1 + if id_min==None or id_min>not_loaded_id: + id_min=not_loaded_id + if id_max==None or id_max0: + result.append({ + 'domain': [['id','>=',id_min],['id','<=',id_max],['parent_id','=',id_msg]], + 'nb_messages': nb, + 'type': 'expandable', + 'parent_id': id_msg, + 'id': id_min + }) + nb=0 + if nb>0: + result.append({ + 'domain': [['id','>=',id_min],['parent_id','=',id_msg]], + 'nb_messages': nb, + 'type': 'expandable', + 'parent_id': id_msg, + 'id': id_min + }) + + + # expandable for limit max + ids = self.search(cr, SUPERUSER_ID, domain+[['id','not in',message_loaded+tree+tree_not]], context=context, limit=1) + if len(ids) > 0: + result.append( + { + 'domain': domain, + 'nb_messages': 0, + 'type': 'expandable', + 'parent_id': parent_id, + 'id': -1 + }); + + + result = sorted(result, key=lambda k: k['id']) return result @@ -472,9 +526,11 @@ 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): + def _notify(self, cr, uid, newid, context=None): """ Add the related record followers to the destination partner_ids. + Call mail_notification.notify to manage the email sending """ + message = self.browse(cr, uid, newid, context=context) partners_to_notify = set([]) # message has no subtype_id: pure log message -> no partners, no one notified if not message.subtype_id: @@ -502,14 +558,6 @@ class mail_message(osv.Model): else: self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(3, message.author_id.id)]}, context=context) - def _notify(self, cr, uid, newid, context=None): - """ Add the related record followers to the destination partner_ids if is not a private message. - Call mail_notification.notify to manage the email sending - """ - message = self.browse(cr, uid, newid, context=context) - if message and (message.is_private!=False and message.is_private!=None): - self._notify_followers(cr, uid, newid, message, context=context) - self.pool.get('mail.notification')._notify(cr, uid, newid, context=context) def copy(self, cr, uid, id, default=None, context=None): diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 6d854d4d701..cc0419352af 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -87,15 +87,8 @@ Inbox mail.wall - - - - - Wall - mail.wall - + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 42b66a53fe5..9f53b4c08b1 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -627,6 +627,7 @@ class mail_thread(osv.AbstractModel): ``(name,content)``, where content is NOT base64 encoded :return: ID of newly created mail.message """ + context = context or {} attachments = attachments or [] assert (not thread_id) or isinstance(thread_id, (int, long)) or \ @@ -678,13 +679,6 @@ class mail_thread(osv.AbstractModel): 'attachment_ids': attachment_ids, 'subtype_id': subtype_id, }) - - # if the parent is private, the message must be private - if parent_id: - msg = messages.browse(cr, uid, parent_id, context=context) - if msg.is_private: - values["is_private"] = msg.is_private - # Avoid warnings about non-existing fields for x in ('from', 'to', 'cc'): values.pop(x, None) diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index 4b6709dd2d8..3507e7c449f 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -18,21 +18,15 @@ - - Wall - - - - Archives - + Sent - + diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 4ffb9013496..364ac7e3165 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -370,7 +370,7 @@ bottom: 0px; top: auto; left: auto; - right: 0; + right: 28px; height: 26px; width: 26px; min-width: 22px; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 8915f1387e1..e0c9ac9b7fc 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -148,8 +148,8 @@ openerp.mail = function(session) { // handle attachment button this.fileupload_id = _.uniqueId('oe_fileupload'); var button_attach = this.$('button.oe_mail_compose_message_attachment'); - var rendered = $( session.web.qweb.render('mail.compose_message.add_attachment', {'widget': this}) ); - rendered.insertBefore(button_attach); + var rendered = session.web.qweb.render('mail.compose_message.add_attachment', {'widget': this}); + $(rendered).insertBefore(button_attach); // move the button inside div.oe_hidden_input_file var input_node = this.$('input[name=ufile]'); button_attach.detach().insertAfter(input_node); @@ -256,10 +256,10 @@ openerp.mail = function(session) { default_res_id: 0, default_parent_id: false }, options.context || {}); - this.id = options.parameters.id || -1; + this.id = -1; this.parent_id= options.parameters.parent_id || false; this.nb_messages = options.parameters.nb_messages || 0; - this.type = 'expandable'; + this.type = options.parameters.type || false; // record options and data this.parent_thread= parent.messages!= undefined ? parent : options.options.thread._parents[0] ; @@ -501,6 +501,9 @@ openerp.mail = function(session) { } else { self.destroy(); } + for(var i in this.thread.messages){ + this.thread.messages[i].animated_destroy({fadeTime:0}); + } }, on_message_delete: function (event) { @@ -595,8 +598,8 @@ openerp.mail = function(session) { display_vote: function () { var self = this; var vote_element = session.web.qweb.render('mail.thread.message.vote', {'widget': self}); - self.$(".placeholder-mail-vote:first").empty(); - self.$(".placeholder-mail-vote:first").html(vote_element); + self.$(".placeholder-mail-vote").empty(); + self.$(".placeholder-mail-vote").html(vote_element); }, }); @@ -876,7 +879,7 @@ openerp.mail = function(session) { fetch_domain = replace_domain ? replace_domain : this.domain; fetch_context = replace_context ? replace_context : this.context; fetch_context.message_loaded= [this.id||0].concat( self.options.thread._parents[0].get_child_ids() ); - + return this.ds_message.call('message_read', [ids, fetch_domain, (this.options.thread.thread_level+1), fetch_context, this.context.default_parent_id || undefined] ).then(this.proxy('switch_new_message')); }, @@ -942,11 +945,11 @@ openerp.mail = function(session) { } } - if(parent_older) - message.insertBefore(parent_older.$el); - else if(parent_newer) + if(parent_newer) message.insertAfter(parent_newer.$el); - else + else if(parent_older) + message.insertBefore(parent_older.$el); + else message.prependTo(thread.list_ul); return message @@ -1095,7 +1098,6 @@ openerp.mail = function(session) { this._super.apply(this, arguments); var searchview_ready = this.load_searchview({}, false); var thread_displayed = this.message_render(); - this.options.domain = this.options.domain.concat(this.search_results['domain']); return (searchview_ready && thread_displayed); }, @@ -1135,14 +1137,19 @@ openerp.mail = function(session) { /** Clean and display the threads */ message_render: function (search) { + var domain = this.options.domain.concat(this.search_results['domain']); + + var domain = _.extend(this.options.domain, search&&search.domain? search.domain : {}); + var context = _.extend(this.options.context, search&&search.context ? search.context : {}); + this.thread = new mail.Thread(this, { - 'domain' : this.options.domain.concat(this.search_results['domain']), - 'context' : _.extend(this.options.context, search&&search.search_results['context'] ? search.search_results['context'] : {}), + 'domain' : domain, + 'context' : context, 'options': { 'thread' :{ 'thread_level': this.options.thread_level, 'use_composer': true, - 'show_header_compose': 1, + 'show_header_compose': 1, }, 'message': { 'show_reply': this.options.thread_level > 0, diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index ab6a63ea6fa..953b8cd9fc8 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -149,6 +149,7 @@ openerp_mail_followers = function(session, mail) { var self = this; var node_user_list = this.$('ul.oe_mail_followers_display').empty(); this.$('div.oe_mail_recthread_followers h4').html(this.options.title + (records.length>=5 ? ' (' + records.length + ')' : '') ); + console.log(records); for(var i=0; i -
                            • +
                            • @@ -170,7 +171,7 @@
                            • -
                            • +
                            • Load more messages ( messages not display)... diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 1485c40570b..7ec37d952bc 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -550,6 +550,48 @@ class test_mail(TestMailMockups): # _compare_structures(struct1[x]['child_ids'], struct2[x]['child_ids'], n + 1) # # print '%send compare' % ('\t' * n) + # # ---------------------------------------- + # # CASE1: Flattening test + # # ---------------------------------------- + + # # Create dummy message structure + # import copy + # tree = [{'id': 2, 'child_nbr': 1, 'child_ids': [ + # {'id': 6, 'child_nbr': 1, 'child_ids': [ + # {'id': 8, 'child_nbr': 0, 'child_ids': []}, + # ]}, + # ]}, + # {'id': 1, 'child_nbr': 3, 'child_ids':[ + # {'id': 7, 'child_nbr': 1, 'child_ids': [ + # {'id': 9, 'child_nbr': 0, 'child_ids': []}, + # ]}, + # {'id': 4, 'child_nbr': 2, 'child_ids': [ + # {'id': 10, 'child_nbr': 0, 'child_ids': []}, + # {'id': 5, 'child_nbr': 0, 'child_ids': []}, + # ]}, + # {'id': 3, 'child_nbr': 0, 'child_ids': []}, + # ]}, + # ] + # # Test: completely flat + # new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 0, limit=15, add_expandable=False) + # _compare_structures(new_tree, new_tree) + # self.assertEqual(len(new_tree), 10, 'message_read_tree_flatten wrong in flat') + # # Test: 1 thread level + # tree_test = [{'id': 2, 'child_ids': [ + # {'id': 8, 'child_ids': []}, {'id': 6, 'child_ids': []}, + # ]}, + # {'id': 1, 'child_ids': [ + # {'id': 10, 'child_ids': []}, {'id': 9, 'child_ids': []}, + # {'id': 7, 'child_ids': []}, {'id': 5, 'child_ids': []}, + # {'id': 4, 'child_ids': []}, {'id': 3, 'child_ids': []}, + # ]}, + # ] + # new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 1, limit=15, add_expandable=False) + # _compare_structures(new_tree, tree_test) + # # Test: 2 thread levels + # new_tree = self.mail_message.message_read_tree_flatten(cr, uid, None, copy.deepcopy(tree), [('type', 'in', 'borderlands')], 2, limit=15, add_expandable=False) + # _compare_structures(new_tree, tree) + # # ---------------------------------------- # # CASE2: message_read test # # ---------------------------------------- diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index b7c51a20125..fbadf76f2fb 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -219,6 +219,7 @@ class mail_compose_message(osv.TransientModel): email(s), rendering any template patterns on the fly if needed. """ if context is None: context = {} + print '**', context active_ids = context.get('active_ids') for wizard in self.browse(cr, uid, ids, context=context): From a3d648f319d29f244f2b8026c031a6b4e70a0398 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 3 Oct 2012 17:58:20 +0200 Subject: [PATCH 523/726] [FIX] account_voucher: fix amount_currency on writeoff line + fixed/improved yaml tests bzr revid: qdp-launchpad@openerp.com-20121003155820-7ozaoklt042b7i6i --- addons/account_voucher/account_voucher.py | 4 +++- addons/account_voucher/test/case1_usd_usd.yml | 14 +++++++++++++- addons/account_voucher/test/case4_cad_chf.yml | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index 36aa8660bc4..8bb8fe4d9b3 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -667,6 +667,7 @@ class account_voucher(osv.osv): #voucher line creation for line in account_move_lines: + if _remove_noise_in_o2m(): continue @@ -1183,6 +1184,7 @@ class account_voucher(osv.osv): account_id = voucher_brw.partner_id.property_account_receivable.id else: account_id = voucher_brw.partner_id.property_account_payable.id + sign = voucher_brw.type == 'payment' and -1 or 1 move_line = { 'name': write_off_name or name, 'account_id': account_id, @@ -1191,7 +1193,7 @@ class account_voucher(osv.osv): 'date': voucher_brw.date, 'credit': diff > 0 and diff or 0.0, 'debit': diff < 0 and -diff or 0.0, - 'amount_currency': company_currency <> current_currency and voucher_brw.writeoff_amount or False, + 'amount_currency': company_currency <> current_currency and (sign * -1 * voucher_brw.writeoff_amount) or False, 'currency_id': company_currency <> current_currency and current_currency or False, 'analytic_account_id': voucher_brw.analytic_id and voucher_brw.analytic_id.id or False, } diff --git a/addons/account_voucher/test/case1_usd_usd.yml b/addons/account_voucher/test/case1_usd_usd.yml index b706e6f0644..300d565f229 100644 --- a/addons/account_voucher/test/case1_usd_usd.yml +++ b/addons/account_voucher/test/case1_usd_usd.yml @@ -216,6 +216,10 @@ assert move_line.credit == 63.00, "Debtor account has wrong entry." elif move_line.amount_currency == 10.00: assert move_line.debit == 9.00, "Writeoff amount is wrong." + elif move_line.amount_currency == 240.00: + assert move_line.debit == 216.00, "Bank entry is wrong." + else: + assert False, "Unrecognized journal entry" - I check the residual amount of Invoice1, should be 20 in amount_currency - @@ -237,7 +241,7 @@ - On the first April, I create the second voucher of payment with values 45 USD, journal USD, - - !record {model: account.voucher, id: account_voucher_2_case1}: + !record {model: account.voucher, id: account_voucher_2_case1, view: view_vendor_receipt_form}: account_id: account.cash amount: 45.0 company_id: base.main_company @@ -323,8 +327,16 @@ assert move_line.debit == 4.75, "Writeoff amount is wrong." elif move_line.debit == 11.5 and move_line.account_id.reconcile: assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_a, "Exchange difference entry for the invoice of 100$ is wrong" + elif move_line.credit == 11.5: + assert move_line.amount_currency == 0.0 elif move_line.debit == 31.0 and move_line.account_id.reconcile: assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_b, "Exchange difference entry for the invoice of 200$ is wrong" + elif move_line.credit == 31.0: + assert move_line.amount_currency == 0.0 + elif move_line.amount_currency == 45.00: + assert move_line.debit == 42.75, "Bank entry is wrong." + else: + assert False, "Unrecognized journal entry" - I check the residual amount of Invoice1, should be 0 in residual currency and 0 in amount_residual and paid - diff --git a/addons/account_voucher/test/case4_cad_chf.yml b/addons/account_voucher/test/case4_cad_chf.yml index a78669c95ef..a2b252497cd 100644 --- a/addons/account_voucher/test/case4_cad_chf.yml +++ b/addons/account_voucher/test/case4_cad_chf.yml @@ -164,7 +164,7 @@ - I check that my currency rate difference is correct. 0 in debit with no amount_currency - - I check that my writeoff is correct. 11.05 credit and 13.26 amount_currency + I check that my writeoff is correct. 11.05 credit and -13.26 amount_currency - !python {model: account.voucher}: | voucher = self.search(cr, uid, [('name', '=', 'First payment: Case 4'), ('partner_id', '=', ref('base.res_partner_19'))]) @@ -179,7 +179,7 @@ elif move_line.debit == 0.00 and move_line.credit == 0.00: assert move_line.amount_currency == 0.00, "Incorrect Currency Difference." elif move_line.credit == 10.61: - assert move_line.amount_currency == 13.26, "Writeoff amount is wrong." + assert move_line.amount_currency == -13.26, "Writeoff amount is wrong." else: assert False, "Wrong entry" - From d2f3bbf4bc77a64deaaf6d3a4e4a381f32bd776a Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 3 Oct 2012 18:16:41 +0200 Subject: [PATCH 524/726] [REV] Undo header template extraction bzr revid: odo@openerp.com-20121003161641-9zodo9ks2bqjjjfd --- openerp/addons/base/ir/ir.xml | 44 +++++++++---------- .../base/module/wizard/base_module_upgrade.py | 4 +- openerp/addons/base/res/res_widget_view.xml | 4 +- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index 2f25f24c394..3189870aa68 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -1170,9 +1170,9 @@ ir.translation
                              - +
                              - +
                              @@ -1733,30 +1733,26 @@ Config Wizard Steps - +
                              + + + + + + + + + +
                              diff --git a/openerp/addons/base/module/wizard/base_module_upgrade.py b/openerp/addons/base/module/wizard/base_module_upgrade.py index 98ea0ac0482..04b7e785e48 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade.py +++ b/openerp/addons/base/module/wizard/base_module_upgrade.py @@ -47,10 +47,10 @@ class base_module_upgrade(osv.osv_memory): ids = self.get_module_list(cr, uid, context=context) if not ids: res['arch'] = '''
                              - +
                              ''' diff --git a/openerp/addons/base/res/res_widget_view.xml b/openerp/addons/base/res/res_widget_view.xml index 764f319de7b..bad582f97db 100644 --- a/openerp/addons/base/res/res_widget_view.xml +++ b/openerp/addons/base/res/res_widget_view.xml @@ -82,11 +82,11 @@ res.widget.wizard
                              - +
                              From 2514a564513918231a43785bfc48df753d16d700 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 3 Oct 2012 18:35:04 +0200 Subject: [PATCH 525/726] [FIX] coresetup: avoid losing whitespace after qweb translations bzr revid: odo@openerp.com-20121003163504-64piei7sjv0b41wx --- addons/web/static/src/js/coresetup.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 4a30a312b7a..d55408ebc83 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -542,13 +542,9 @@ instance.web.qweb.preprocess_node = function() { if (translation && translation.value === 'off') { return; } - var ts = _.str.trim(this.node.data); - if (ts.length === 0) { - return; - } - var tr = instance.web._t(ts); - if (tr !== ts) { - this.node.data = tr; + var match = /^(\s*)(.+?)(\s*)$/.exec(this.node.data); + if (match) { + this.node.data = match[1] + instance.web._t(match[2]) + match[3]; } break; case 1: From 3c26ec305a6aa003a6d764048a82bd39a16e5792 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse <> Date: Thu, 4 Oct 2012 06:46:24 +0200 Subject: [PATCH 526/726] [IMP] mail: move the code from publisher_warranty to mail bzr revid: stw@openerp.com-20121004044624-hwa3kztl58zrjguh --- addons/mail/__init__.py | 1 + addons/mail/data/mail_data.xml | 14 +++++ addons/mail/mail_message.py | 2 +- addons/mail/update.py | 112 +++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 addons/mail/update.py diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 92e882ae6d8..abf714ad534 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -33,6 +33,7 @@ import report import wizard import res_config import mail_group_menu +import update # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index 5fe1ee45b1d..522cbe8c7a7 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -13,6 +13,20 @@ + + Update Notification + + + 1 + weeks + -1 + + + + + 1000 + + comment diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index bbf68509277..9c873a31097 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -504,7 +504,7 @@ class mail_message(osv.Model): if not values.get('message_id') and values.get('res_id') and values.get('model'): values['message_id'] = tools.generate_tracking_message_id('%(model)s-%(res_id)s' % values) newid = super(mail_message, self).create(cr, uid, values, context) - self._notify(cr, 1, newid, context=context) + self._notify(cr, SUPERUSER_ID, newid, context=context) return newid def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): diff --git a/addons/mail/update.py b/addons/mail/update.py new file mode 100644 index 00000000000..0e10ee0a7f1 --- /dev/null +++ b/addons/mail/update.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +import datetime +import logging +import sys +import urllib +import urllib2 + +import pooler +import release +from osv import osv, fields +from tools.translate import _ +from tools.safe_eval import safe_eval +from tools.config import config +from tools import misc + +_logger = logging.getLogger(__name__) + +""" +Time interval that will be used to determine up to which date we will +check the logs to see if a message we just received was already logged. +@type: datetime.timedelta +""" +_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365) + +def get_sys_logs(cr, uid): + """ + Utility method to send a publisher warranty get logs messages. + """ + pool = pooler.get_pool(cr.dbname) + + dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') + db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date') + limit_date = datetime.datetime.now() + limit_date = limit_date - datetime.timedelta(15) + limit_date_str = limit_date.strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT) + nbr_users = pool.get("res.users").search(cr, uid, [], count=True) + nbr_active_users = pool.get("res.users").search(cr, uid, [("date", ">=", limit_date_str)], count=True) + nbr_share_users = False + nbr_active_share_users = False + if "share" in pool.get("res.users")._all_columns: + nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True) + nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True) + user = pool.get("res.users").browse(cr, uid, uid) + msg = { + "dbuuid": dbuuid, + "nbr_users": nbr_users, + "nbr_active_users": nbr_active_users, + "nbr_share_users": nbr_share_users, + "nbr_active_share_users": nbr_active_share_users, + "dbname": cr.dbname, + "db_create_date": db_create_date, + "version": release.version, + "language": user.lang, + } + msg.update(pool.get("res.company").read(cr,uid,[1],["name","email","phone"])[0]) + + add_arg = {"timeout":30} if sys.version_info >= (2,6) else {} + arguments = {'arg0': msg, "action": "update",} + arguments_raw = urllib.urlencode(arguments) + + url = config.get("publisher_warranty_url") + uo = urllib2.urlopen(url, arguments_raw, **add_arg) + result = {} + try: + submit_result = uo.read() + result = safe_eval(submit_result) + finally: + uo.close() + return result + +class publisher_warranty_contract(osv.osv): + _name = "publisher_warranty.contract" + + def update_notification(self, cr, uid, ids, cron_mode=True, context=None): + """ + Send a message to OpenERP's publisher warranty server to check the + validity of the contracts, get notifications, etc... + + @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron). + @type cron_mode: boolean + """ + try: + try: + result = get_sys_logs(cr, uid) + except Exception: + if cron_mode: # we don't want to see any stack trace in cron + return False + _logger.debug("Exception while sending a get logs messages", exc_info=1) + raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server.")) + limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT) + # old behavior based on res.log; now on mail.message, that is not necessarily installed + proxy = self.pool.get('mail.message') + + model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'group_all_employees') + + for message in result["messages"]: + values = { + 'body' : message, + 'model' : 'mail.group', + 'res_id' : res_id, + 'user_id' : False, + } + proxy.create(cr, uid, values, context=context) + except Exception: + if cron_mode: + return False # we don't want to see any stack trace in cron + else: + raise + return True + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + From 2fdcc19dcb7c7d3a147d3630155f870cfc9f7262 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Thu, 4 Oct 2012 05:19:06 +0000 Subject: [PATCH 527/726] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20121004051906-19h9v4f5p768ky0x --- openerp/addons/base/i18n/ab.po | 4 +- openerp/addons/base/i18n/af.po | 4 +- openerp/addons/base/i18n/am.po | 4 +- openerp/addons/base/i18n/ar.po | 4 +- openerp/addons/base/i18n/bg.po | 4 +- openerp/addons/base/i18n/bs.po | 4 +- openerp/addons/base/i18n/ca.po | 4 +- openerp/addons/base/i18n/cs.po | 4 +- openerp/addons/base/i18n/da.po | 4 +- openerp/addons/base/i18n/de.po | 1500 +++++++++++++++++++++----- openerp/addons/base/i18n/el.po | 4 +- openerp/addons/base/i18n/en_GB.po | 4 +- openerp/addons/base/i18n/es.po | 4 +- openerp/addons/base/i18n/es_AR.po | 57 +- openerp/addons/base/i18n/es_CL.po | 4 +- openerp/addons/base/i18n/es_CR.po | 4 +- openerp/addons/base/i18n/es_EC.po | 4 +- openerp/addons/base/i18n/es_MX.po | 4 +- openerp/addons/base/i18n/et.po | 4 +- openerp/addons/base/i18n/eu.po | 4 +- openerp/addons/base/i18n/fa.po | 82 +- openerp/addons/base/i18n/fa_AF.po | 4 +- openerp/addons/base/i18n/fi.po | 4 +- openerp/addons/base/i18n/fr.po | 4 +- openerp/addons/base/i18n/gl.po | 4 +- openerp/addons/base/i18n/gu.po | 4 +- openerp/addons/base/i18n/he.po | 4 +- openerp/addons/base/i18n/hr.po | 4 +- openerp/addons/base/i18n/hu.po | 4 +- openerp/addons/base/i18n/hy.po | 4 +- openerp/addons/base/i18n/id.po | 4 +- openerp/addons/base/i18n/is.po | 4 +- openerp/addons/base/i18n/it.po | 4 +- openerp/addons/base/i18n/ja.po | 4 +- openerp/addons/base/i18n/ka.po | 4 +- openerp/addons/base/i18n/kk.po | 4 +- openerp/addons/base/i18n/ko.po | 4 +- openerp/addons/base/i18n/lt.po | 4 +- openerp/addons/base/i18n/lv.po | 4 +- openerp/addons/base/i18n/mk.po | 4 +- openerp/addons/base/i18n/mn.po | 4 +- openerp/addons/base/i18n/nb.po | 4 +- openerp/addons/base/i18n/nl.po | 31 +- openerp/addons/base/i18n/nl_BE.po | 4 +- openerp/addons/base/i18n/pl.po | 4 +- openerp/addons/base/i18n/pt.po | 4 +- openerp/addons/base/i18n/pt_BR.po | 245 ++++- openerp/addons/base/i18n/ro.po | 4 +- openerp/addons/base/i18n/ru.po | 4 +- openerp/addons/base/i18n/sk.po | 4 +- openerp/addons/base/i18n/sl.po | 4 +- openerp/addons/base/i18n/sq.po | 4 +- openerp/addons/base/i18n/sr.po | 4 +- openerp/addons/base/i18n/sr@latin.po | 4 +- openerp/addons/base/i18n/sv.po | 4 +- openerp/addons/base/i18n/th.po | 4 +- openerp/addons/base/i18n/tlh.po | 4 +- openerp/addons/base/i18n/tr.po | 4 +- openerp/addons/base/i18n/uk.po | 4 +- openerp/addons/base/i18n/ur.po | 4 +- openerp/addons/base/i18n/vi.po | 4 +- openerp/addons/base/i18n/zh_CN.po | 4 +- openerp/addons/base/i18n/zh_HK.po | 4 +- openerp/addons/base/i18n/zh_TW.po | 4 +- 64 files changed, 1720 insertions(+), 431 deletions(-) diff --git a/openerp/addons/base/i18n/ab.po b/openerp/addons/base/i18n/ab.po index ac0496223b8..6186cb742ec 100644 --- a/openerp/addons/base/i18n/ab.po +++ b/openerp/addons/base/i18n/ab.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:09+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po index 608d495e608..10c4ef3a73d 100644 --- a/openerp/addons/base/i18n/af.po +++ b/openerp/addons/base/i18n/af.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:09+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po index 25698246ad6..27aaf0c5a05 100644 --- a/openerp/addons/base/i18n/am.po +++ b/openerp/addons/base/i18n/am.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po index 7c09854ed2a..180e7fc450e 100644 --- a/openerp/addons/base/i18n/ar.po +++ b/openerp/addons/base/i18n/ar.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po index d44cade6cce..cb97a8e030b 100644 --- a/openerp/addons/base/i18n/bg.po +++ b/openerp/addons/base/i18n/bg.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po index b5fc1a1f74b..138f14299fd 100644 --- a/openerp/addons/base/i18n/bs.po +++ b/openerp/addons/base/i18n/bs.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po index afd47adabb8..823ff68dda8 100644 --- a/openerp/addons/base/i18n/ca.po +++ b/openerp/addons/base/i18n/ca.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po index 22250c36dde..f35a33d13a4 100644 --- a/openerp/addons/base/i18n/cs.po +++ b/openerp/addons/base/i18n/cs.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" "X-Poedit-Language: Czech\n" #. module: base diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po index 601a032c80b..2a2ed7015c9 100644 --- a/openerp/addons/base/i18n/da.po +++ b/openerp/addons/base/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po index f60a6ef6a22..8b79ca7b746 100644 --- a/openerp/addons/base/i18n/de.po +++ b/openerp/addons/base/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh @@ -35,7 +35,7 @@ msgstr "Datum/Zeit" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "Aufgaben EMail Integration" +msgstr "EMail-Integration in Aufgaben" #. module: base #: code:addons/fields.py:582 @@ -51,7 +51,7 @@ msgstr "" #: field:ir.ui.view,arch:0 #: field:ir.ui.view.custom,arch:0 msgid "View Architecture" -msgstr "Aufbau ansehen" +msgstr "Aufbau des Ansichts-Formulars" #. module: base #: model:ir.module.module,description:base.module_project @@ -105,7 +105,7 @@ msgstr "Arbeitsablauf" #. module: base #: selection:ir.sequence,implementation:0 msgid "No gap" -msgstr "Ohne Lücken" +msgstr "Lückenlos" #. module: base #: selection:base.language.install,lang:0 @@ -5336,6 +5336,18 @@ msgid "" "modules like share, lunch, pad, idea, survey and subscription.\n" " " msgstr "" +"\n" +"Modul zur Installation von versteckten Extras wie Lunch, Survey, Idee, " +"Teilen, usw.\n" +"=============================================================================" +"==============\n" +"\n" +"Macht versteckte Extra Konfigurationen verfügbar, mittels denen Sie Module " +"wie\n" +"Teilen (gemeinsam nutzen), Mittagessen (lunch), pad, Idee, Fragebogen und " +"Abonnement \n" +"einrichten können.\n" +" " #. module: base #: model:ir.module.category,name:base.module_category_specific_industry_applications @@ -9198,7 +9210,7 @@ msgstr "Kontakt" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_at msgid "Austria - Accounting" -msgstr "Österreich - Buchhaltung" +msgstr "Österreichische Buchführung" #. module: base #: model:ir.model,name:base.model_ir_ui_menu @@ -9557,7 +9569,7 @@ msgstr "Plattform für Zusammenarbeit" #. module: base #: model:ir.module.module,shortdesc:base.module_account_anglo_saxon msgid "Anglo-Saxon Accounting" -msgstr "Angelsächsische Buchungslogik" +msgstr "Angelsächsische Buchführung" #. module: base #: model:res.country,name:base.np @@ -10756,7 +10768,7 @@ msgstr "" #. module: base #: model:ir.module.module,description:base.module_google_base_account msgid "The module adds google user in res user" -msgstr "" +msgstr "Dieses Modul fügt google-Benutzer in res.user ein" #. module: base #: selection:base.language.install,state:0 @@ -10905,6 +10917,7 @@ msgstr "Just in Time Terminierung" #: model:ir.module.module,shortdesc:base.module_account_bank_statement_extensions msgid "Bank Statement extensions to support e-banking" msgstr "" +"Erweiterung bezüglich Bank-Kontoauszügen zur Unterstützung von eBanking" #. module: base #: view:ir.actions.server:0 @@ -10983,6 +10996,19 @@ msgid "" "fund status.\n" " " msgstr "" +"\n" +"Beschaffung von Fördermitteln.\n" +"==============================\n" +"\n" +"Wenn Sie Ihre Organisation oder eine Kampagne unterstützen wollen, können " +"Sie alle\n" +"Maßnahmen zur Beschaffung von Geldern hier nachvollziehen. Das Menü eröffnet " +"eine\n" +"Liste in der Sie Spendenbeschreibungen, eMail, Verlauf und " +"Erfolgswahrscheinlichkeiten.\n" +"Einige Aktionsschaltflächen ermöglichen die einfache Veränderung ihres " +"Mittelstatus\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_sale_margin @@ -11056,6 +11082,12 @@ msgid "" "This module is the base module for other multi-company modules.\n" " " msgstr "" +"\n" +"Dieses Modul dient der Verwaltung einer Mehrfach-Unternehmens-Umgebung.\n" +"=================================================================\n" +"\n" +"Dieses Modul ist die Basis für andere Module für Mehrfach-Unternehmen.\n" +" " #. module: base #: sql_constraint:res.currency:0 @@ -11168,6 +11200,33 @@ msgid "" "module named account_voucher.\n" " " msgstr "" +"\n" +"Finanzbuchhaltung und Finanzverwaltung.\n" +"====================================\n" +"\n" +"Modul für Finanzen und Buchhaltung liefert:\n" +"----------------------------------------------------------------------\n" +"Allgemeine Finanzbuchhaltung\n" +"Kostenstellenrechnung\n" +"Mandantenfähigkeit\n" +"Steuerverwaltung\n" +"Budgetverwaltung\n" +"Kunden- und Lieferantenrechnungen\n" +"Kontoauszüge der Bank\n" +"Mahnwesen Partnerbezogen\n" +"\n" +"Erzeugt eine Pinnwand für Buchhalter mit:\n" +"* Liste zu bewilligender Kundenrechnungen\n" +"* Unternehmensanalyse\n" +"* Diagramm überfälliger Forderungen\n" +"* Diagramm der Finanzen\n" +"\n" +"Die Prozesse, wie Führung des Hauptbuchs, werden durch vorgegebene " +"Finanzberichte (Verschiebung von Einträgen\n" +"oder Gruppierung werden im Berichtsblatt eingestellt) im bestimmten " +"Geschäftsjahr. Zur Vorbereitung von \n" +"Gutschriften gibt es ein separates Modul namens account_voucher.\n" +" " #. module: base #: help:ir.actions.act_window,view_type:0 @@ -11236,6 +11295,12 @@ msgid "" "- SSL/TLS: SMTP sessions are encrypted with SSL/TLS through a dedicated port " "(default: 465)" msgstr "" +"Wählen Sie das Verbindungs-Verschlüsselungs-Schema:\n" +" - Keine: SMTP-Sitzungen erfolgen im Klartext.\n" +" - TLS (STARTTLS): TLS -Verschlüsselung wird zu Beginn der SMTP-Sitzung " +"angefordert (empfohlen)\n" +" - SSL/TLS: SMTP-Sitzungen sind mit SSL/TLS über einen didizierten Port " +"(Standard 465) verschlüsselt" #. module: base #: view:ir.model:0 @@ -11254,6 +11319,14 @@ msgid "" "modules like base_report_designer and base_report_creator.\n" " " msgstr "" +"\n" +"Installationsassistent für versteckte Berichtsmodule.\n" +"===============================================\n" +"\n" +"Macht versteckte Berichtsmodule verfügbar. Mit diesen können Sie dann Module " +"wie\n" +"base_report_designer und base_report_creator installieren.\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_base_synchro @@ -11315,7 +11388,7 @@ msgstr "Ansicht" #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_sale_faq msgid "Wiki: Sale FAQ" -msgstr "" +msgstr "Wiki: Verkaufs-FAQ" #. module: base #: selection:ir.module.module,state:0 @@ -11359,6 +11432,13 @@ msgid "" "outlook, Sunbird, ical, ...\n" " " msgstr "" +"\n" +"Ermöglicht die Sysnchronisierung mit Kalendern anderer Anwendungen.\n" +"===============================================================\n" +"\n" +"Ermöglicht Ihnen den Abgleich der OpenERP-Kalender mit denen Ihres Telefons, " +"von Outlook, Sunbird, iCal, ...\n" +" " #. module: base #: model:res.country,name:base.lr @@ -11448,7 +11528,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_google_map msgid "Google Maps on Customers" -msgstr "" +msgstr "Kunden in Google-Maps finden" #. module: base #: model:ir.actions.report.xml,name:base.preview_report @@ -11557,12 +11637,12 @@ msgstr "Fehler !" #. module: base #: model:ir.module.module,shortdesc:base.module_marketing_campaign_crm_demo msgid "Marketing Campaign - Demo" -msgstr "" +msgstr "Beispiel einer Marketing-Kampagne" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_hr_recruitment msgid "eMail Gateway for Applicants" -msgstr "" +msgstr "eMail Zugang für Bewerber" #. module: base #: model:ir.module.module,shortdesc:base.module_account_coda @@ -11589,7 +11669,7 @@ msgstr "Diese Methode existiert zwischenzeitlich nicht mehr" #. module: base #: model:ir.module.module,shortdesc:base.module_import_google msgid "Google Import" -msgstr "" +msgstr "Google-Import" #. module: base #: model:res.partner.category,name:base.res_partner_category_12 @@ -11665,7 +11745,7 @@ msgstr "Zu erledigen" #. module: base #: model:ir.module.module,shortdesc:base.module_product_visible_discount msgid "Prices Visible Discounts" -msgstr "" +msgstr "Sichtbare Preisnachlässe" #. module: base #: field:ir.attachment,datas:0 @@ -11906,6 +11986,12 @@ msgid "" "Provide Templates for Chart of Accounts, Taxes for Uruguay\n" "\n" msgstr "" +"\n" +"Allgemeiner Kontenplan für Uruguay\n" +"================================\n" +"\n" +"Liefert Vorlagen für Kontenplan und Steuern für Uruguay.\n" +"\n" #. module: base #: help:res.company,bank_ids:0 @@ -11987,7 +12073,7 @@ msgstr "Estonian / Eesti keel" #. module: base #: field:res.partner,email:0 msgid "E-mail" -msgstr "E-Mail" +msgstr "EMail" #. module: base #: selection:ir.module.module,license:0 @@ -12030,6 +12116,16 @@ msgid "" " http://files.me.com/nbessi/06n92k.mov\n" " " msgstr "" +"\n" +"Beispiele für den Webkit-Berichtserzeuger (report_webkit).\n" +"===================================================\n" +"\n" +"Eine Beispiel-Rechnung wird mit eingerichtet, als auch ein Assistent um\n" +"Webkit-Berichte jedem Dokument des Systems hinzuzufügen.\n" +"\n" +"Sie müssen nur noch die \"Druck\"-Schalter mittels Assistent anlegen.\n" +"Siehe auch: http://files.me.com/nbessi/06n92k.mov\n" +" " #. module: base #: selection:base.language.install,lang:0 @@ -12059,8 +12155,8 @@ msgid "" "You can not read this document (%s) ! Be sure your user belongs to one of " "these groups: %s." msgstr "" -"Sie haben kein Leserecht für diesen Satz (%s) ! Stellen Sie sicher, dass der " -"Benutzer Mitglied der folgenden Gruppe ist: %s." +"Sie haben kein Leserecht für dieses Dokument (%s)! Stellen Sie sicher, dass " +"Sie Mitglied der folgenden Gruppe sind: %s." #. module: base #: view:res.bank:0 @@ -12087,7 +12183,7 @@ msgstr "Installierte Version" #. module: base #: selection:base.language.install,lang:0 msgid "Mongolian / монгол" -msgstr "Mongolian / монгол" +msgstr "Mongolisch / монгол" #. module: base #: model:res.country,name:base.mr @@ -12113,22 +12209,32 @@ msgid "" " * Product Attributes\n" " " msgstr "" +"\n" +"Ein Modul, welches Hersteller-Information im Produktformular hinzu.\n" +"==========================================================\n" +"\n" +"Sie können die folgenden Angaben zu Produkten erfassen:\n" +" * Hersteller\n" +" * Produktname beim Hersteller\n" +" * Produktkennung (Bestellnummer) des Herstellers\n" +" * Produktmerkmale\n" +" " #. module: base #: model:ir.model,name:base.model_ir_actions_todo_category msgid "Configuration Wizard Category" -msgstr "Konfigurations Assistent Kategorie" +msgstr "Assistent zur Konfiguration der Kategorien" #. module: base #: view:base.module.update:0 msgid "Module update result" -msgstr "Modul Aktualisierung Ergebnis" +msgstr "Ergebnis der Modulaktualisierung" #. module: base #: view:workflow.activity:0 #: field:workflow.workitem,act_id:0 msgid "Activity" -msgstr "Aktion" +msgstr "Aktivität" #. module: base #: view:res.partner:0 @@ -12139,7 +12245,7 @@ msgstr "Postanschrift" #. module: base #: field:res.company,parent_id:0 msgid "Parent Company" -msgstr "Konzern" +msgstr "Stamm-Unternehmen" #. module: base #: model:ir.module.module,description:base.module_base_iban @@ -12154,6 +12260,15 @@ msgid "" "accounts with a single statement.\n" " " msgstr "" +"\n" +"Dieses Modul stellt die Basis für IBAN (Intern. Bank Accounting Number) -" +"Bankkonten mit Gültigkeitsprüfung.\n" +"=============================================================================" +"==============\n" +"\n" +"Bietet die Möglichkeit richtig dargestellte lokale Bankkonten durch IBAN-" +"Konten in einem Ausdruck.\n" +" " #. module: base #: model:ir.model,name:base.model_ir_mail_server @@ -12183,7 +12298,7 @@ msgstr "" #. module: base #: field:res.currency.rate,rate:0 msgid "Rate" -msgstr "Zinskondition" +msgstr "Wechselkurs" #. module: base #: model:res.country,name:base.cg @@ -12209,7 +12324,7 @@ msgstr "Bundesland" #. module: base #: model:ir.ui.menu,name:base.next_id_5 msgid "Sequences & Identifiers" -msgstr "Sequenzen und Identifizierungsmerkmale" +msgstr "Folgen- und Identifizierungsmerkmale" #. module: base #: model:ir.module.module,description:base.module_l10n_th @@ -12221,6 +12336,12 @@ msgid "" "Thai accounting chart and localization.\n" " " msgstr "" +"\n" +"Kontenrahmen für Thailand.\n" +"===============================\n" +"\n" +"Thailändische Kontenrahmen und Lokalisierung.\n" +" " #. module: base #: model:res.country,name:base.kn @@ -12244,6 +12365,14 @@ msgid "" " * Company Contribution Management\n" " " msgstr "" +"\n" +"Allgemeine Lohnbuchhaltung.\n" +"==========================\n" +"\n" +" * Spesenerfassung\n" +" * Auszahlungserfassung\n" +" * Verwaltung von Unternehmensbeiträgen\n" +" " #. module: base #: code:addons/base/res/res_currency.py:190 @@ -12253,9 +12382,10 @@ msgid "" "for the currency: %s \n" "at the date: %s" msgstr "" -"Konnte keinen Wechselkurs ermitteln, \n" -"für die Währung %s \n" -"am Stichtag: %s" +"Konnte für die \n" +"Währung %s am\n" +"Stichtag: %s\n" +"keinen Wechselkurs ermitteln." #. module: base #: model:ir.module.module,description:base.module_point_of_sale @@ -12275,6 +12405,20 @@ msgid "" " * Allow to refund former sales.\n" " " msgstr "" +"\n" +"Dieses Modul stellt einen schnellen und einfachen Verkaufsvorgang zur " +"Verfügung.\n" +"====================================================================\n" +"\n" +"Hauptmerkmale:\n" +" * Schnelle Erfassung der Verkäufe.\n" +" * Auswahl einer Zahlweise (einfach) oder mehrere Zahlungen mit versch. " +"Zahlweisen.\n" +" * Rückgeldermittlung.\n" +" * Anlegen und Bestätigung der Kommissionierung (autom.)\n" +" * Benutzer kann Rechnung autom. anlegen.\n" +" * Ermöglicht vorige Verkäufe gutzuschreiben.\n" +" " #. module: base #: model:ir.actions.act_window,help:base.action_ui_view_custom @@ -12282,8 +12426,8 @@ msgid "" "Customized views are used when users reorganize the content of their " "dashboard views (via web client)" msgstr "" -"Individuelle Ansichten werden aktuell z.B für die persönliche Pinnwand " -"Ansichte eingesetzt." +"Individuelle Ansichten werden aktuell z. B. für die persönliche Pinnwand-" +"Ansichten eingesetzt." #. module: base #: help:publisher_warranty.contract,check_opw:0 @@ -12291,6 +12435,8 @@ msgid "" "Checked if this is an OpenERP Publisher's Warranty contract (versus older " "contract types" msgstr "" +"Anwählen, wenn dies ein OpenERP Herausgeber-Gewährleistungsvertrag ist (im " +"Gegensatz zu älteren Vertragsarten)" #. module: base #: field:ir.model.fields,model:0 @@ -12336,7 +12482,7 @@ msgstr "" #. module: base #: help:ir.model.fields,model_id:0 msgid "The model this field belongs to" -msgstr "Das Datenmodell zu dem dieses Feld angehört." +msgstr "Das Datenmodell dem dieses Feld angehört." #. module: base #: model:res.country,name:base.mq @@ -12354,11 +12500,21 @@ msgid "" "for Wiki Sale FAQ.\n" " " msgstr "" +"\n" +"Dieses Modul stellt eine Wiki mit Vorlagen zu Fragen & Antworten des " +"Verkaufs zur Verfügung.\n" +"=============================================================================" +"=\n" +"\n" +"Es werden Beispieldaten angelegt. Dabei werden eine Wiki-Gruppe und eine " +"Wiki-Seite als\n" +"Grundlage für eine Wiki mit \"Fragen & Antworten zum Verkauf\" angelegt.\n" +" " #. module: base #: view:ir.sequence.type:0 msgid "Sequences Type" -msgstr "Sequenz Typ" +msgstr "Folgenart" #. module: base #: model:ir.module.module,description:base.module_base_action_rule @@ -12376,6 +12532,19 @@ msgid "" "trigger an automatic reminder email.\n" " " msgstr "" +"\n" +"Dieses Modul führt regelbasierte Aktionen auf Objekte in das System ein.\n" +"=============================================================\n" +"\n" +"Automatisierte Aktionen verwenden Sie für automatisch ausgelöste Aktionen\n" +"in den unterschiedlichsten Sichten.\n" +"\n" +"Beispiel: Einem Fall in Vorverhandlungen (Leads) mit einem bestimmten \n" +"Benutzer wird automatisch ein bestimmtes Verkaufsteam zugewiesen. Oder\n" +"eine nach 14 Tagen unverändert im Zustand \"wartend\" befindliche \n" +"Gelegenheit löst automatisch eine Erinnerungs-Mitteilung an den \n" +"zuständigen Mitarbeiter aus.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.res_request-act @@ -12417,6 +12586,15 @@ msgid "" "The wizard to launch the report has several options to help you get the data " "you need.\n" msgstr "" +"\n" +"Fügt Berichte zum Menü der Produkte hinzu, welches Verkaufszahlen, Käufe, " +"Margen und \n" +"andere interessante Indikatoren aus Rechnungen errechnet.\n" +"==========================================================================\n" +"\n" +"Der Assistent bietet für die Berichterstellung diverse Optionen, um bei der " +"Ermittelung der \n" +"gewünschten Daten behilflich zu sein.\n" #. module: base #: model:res.country,name:base.al @@ -12450,27 +12628,28 @@ msgid "" "Please be patient, this operation may take a few minutes (depending on the " "number of modules currently installed)..." msgstr "" -"Geduld ! Dieser Vorgang kann einige Zeit dauern (in Abhängigkeit von der " -"Anzahl der installierten Module)" +"Bitte geduldig sein! Dieser Vorgang kann einige Zeit dauern (Abhängig von " +"der Anzahl derzeit installierter Module)" #. module: base #: field:ir.ui.menu,child_id:0 msgid "Child IDs" -msgstr "untergeordnete ID's" +msgstr "untergeordnete Kennungen" #. module: base #: code:addons/base/ir/ir_actions.py:748 #: code:addons/base/ir/ir_actions.py:751 #, python-format msgid "Problem in configuration `Record Id` in Server Action!" -msgstr "Problem in Konfiguration 'Datensatznummer' in der Server Aktion!" +msgstr "" +"Problem mit der Konfiguration der 'Datensatznummer' in Server-Aktion!" #. module: base #: code:addons/orm.py:2682 #: code:addons/orm.py:2692 #, python-format msgid "ValidateError" -msgstr "ValidierungsFehler" +msgstr "Validierungsfehler" #. module: base #: view:base.module.import:0 @@ -12489,6 +12668,13 @@ msgid "" "Price and Cost Price.\n" " " msgstr "" +"\n" +"Dieses Modul fügt die \"Marge\" auf Verkaufsaufträge hinzu.\n" +"================================================\n" +"\n" +"Dies gibt die Gewinnspanne durch Berechnung der Differenz zwischen \n" +"Einzelpreis (VK) und Anschaffungskosten (EK) an.\n" +" " #. module: base #: model:ir.actions.act_window,help:base.action_res_bank_form @@ -12499,12 +12685,12 @@ msgstr "" #. module: base #: view:base.module.import:0 msgid "Import module" -msgstr "Import Module" +msgstr "Import-Modul" #. module: base #: field:ir.actions.server,loop_action:0 msgid "Loop Action" -msgstr "Schleife Aktion" +msgstr "Wiederholungsaktion" #. module: base #: help:ir.actions.report.xml,report_file:0 @@ -12512,7 +12698,7 @@ msgid "" "The path to the main report file (depending on Report Type) or NULL if the " "content is in another field" msgstr "" -"Das Verzeichnis zum Hauptreport (je nach Report Typ) oder NULL, wenn der " +"Das Verzeichnis zum Hauptreport (je nach Reportart) oder NULL, wenn der " "Inhalt in einem anderen Feld steht" #. module: base @@ -12526,7 +12712,7 @@ msgstr "Laos" #: field:res.company,email:0 #: field:res.users,user_email:0 msgid "Email" -msgstr "E-Mail:" +msgstr "EMail" #. module: base #: field:res.users,action_id:0 @@ -12574,6 +12760,17 @@ msgid "" " - uid: current user id\n" " - context: current context" msgstr "" +"Bedingung, die geprüft wird bevor die Aktion ausgeführt wird, anderenfalls " +"die Auführung unterbindet.\n" +"Beispiel: object.list_price > 5000\n" +"Es ist ein Python-Ausdruck der folgende Werte nutzen kann:\n" +"- self: ORM-Modell des Datensatzes über den die Aktion ausgelöst wurde\n" +"- object oder obj: browse_record über den die Aktion ausgelöst wurde\n" +"- pool: Pool des ORM-Modells (also z. B. : self.pool)\n" +"- time: Python Zeitmodul\n" +"- cr: Datenbank-Cursor\n" +"- uid: Nutzerkennung des aktuellen Benutzers\n" +"- context: Aktueller Kontext" #. module: base #: view:ir.rule:0 @@ -12599,17 +12796,17 @@ msgstr "Andere geschützte" #. module: base #: model:res.country,name:base.ec msgid "Ecuador" -msgstr "Ekuador" +msgstr "Equador" #. module: base #: selection:workflow.activity,kind:0 msgid "Stop All" -msgstr "Stop" +msgstr "Alle stoppen" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_user_function msgid "Jobs on Contracts" -msgstr "" +msgstr "Vertragsarbeiten" #. module: base #: model:ir.module.module,description:base.module_import_sugarcrm @@ -12619,13 +12816,18 @@ msgid "" " \"Contacts\", \"Employees\", Meetings, Phonecalls, Emails, and " "Project, Project Tasks Data into OpenERP Module." msgstr "" +"Dieses Modul importiert \"Leads\", \"Gelegenheiten\", \"Benutzer\", " +"\"Konten\", \"Kontakte\",\n" +"\"Mitarbeiter\", \"Termine\", \"Anrufe\", \"EMails\" und \"Projekte\" bzw. " +"\"Projektaufgaben\" \n" +"in das OpenERP-System." #. module: base #: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_add_wizard #: model:ir.ui.menu,name:base.menu_publisher_warranty_contract_add #: view:publisher_warranty.contract.wizard:0 msgid "Register a Contract" -msgstr "Registrieren" +msgstr "Vertrag aufnehmen" #. module: base #: model:ir.module.module,description:base.module_l10n_ve @@ -12636,6 +12838,13 @@ msgid "" "\n" "Este módulo es para manejar un catálogo de cuentas ejemplo para Venezuela.\n" msgstr "" +"\n" +"Dieses Modul Modul stellt Kontenrahmen der Buchhaltung in Venezuela für " +"OpenERP zur Verfügung.\n" +"=============================================================================" +"=====\n" +"\n" +"Este módulo es para manejar un catálogo de cuentas ejemplo para Venezuela.\n" #. module: base #: view:ir.model.data:0 @@ -12650,7 +12859,7 @@ msgstr "3. %x ,%X ==> 12/05/08, 18:25:20" #. module: base #: selection:ir.model.fields,on_delete:0 msgid "Cascade" -msgstr "Kaskadierend" +msgstr "Mehrstufig" #. module: base #: field:workflow.transition,group_id:0 @@ -12670,7 +12879,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Arabic / الْعَرَبيّة" -msgstr "Arabic / الْعَرَبيّة" +msgstr "Arabisch / الْعَرَبيّة" #. module: base #: model:ir.module.module,shortdesc:base.module_web_hello @@ -12680,7 +12889,7 @@ msgstr "Hallo" #. module: base #: view:ir.actions.configuration.wizard:0 msgid "Next Configuration Step" -msgstr "Nächste Konfiguration" +msgstr "Nächster Konfigurationsschritt" #. module: base #: field:res.groups,comment:0 @@ -12699,12 +12908,12 @@ msgstr "Personalleiter" #: field:ir.rule,domain_force:0 #: field:res.partner.title,domain:0 msgid "Domain" -msgstr "Domain" +msgstr "Domäne" #. module: base #: model:ir.module.module,shortdesc:base.module_marketing_campaign msgid "Marketing Campaigns" -msgstr "Marketing Kampagnen" +msgstr "Marketing-Kampagnen" #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:144 @@ -12730,7 +12939,7 @@ msgstr "Aktualisere Übersetzungen" #. module: base #: field:workflow.activity,join_mode:0 msgid "Join Mode" -msgstr "Anschlußmodus" +msgstr "Vereinigungs-Modus" #. module: base #: field:res.users,context_tz:0 @@ -12740,7 +12949,7 @@ msgstr "Zeitzone" #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_faq msgid "Wiki: Internal FAQ" -msgstr "" +msgstr "Wiki: Interne Fragen & Antworten" #. module: base #: model:ir.model,name:base.model_ir_actions_report_xml @@ -12761,13 +12970,23 @@ msgid "" "handle an issue.\n" " " msgstr "" +"\n" +"Dieses Modul fügt Unterstützung für Zeitnachweise zu Problemen und -Fehlern " +"der Projektplanung hinzu.\n" +"=============================================================================" +"===========\n" +"\n" +"Arbeitsprotokolle (Rapporte) können verwendet werden, um die für " +"Problembehebung und \n" +"Fehlerbeseitigung aufgebrachte Zeit festzuhalten und Nachweis zu führen.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.ir_sequence_form #: view:ir.sequence:0 #: model:ir.ui.menu,name:base.menu_ir_sequence_form msgid "Sequences" -msgstr "Sequenzen" +msgstr "Folgen" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_miss @@ -12782,7 +13001,9 @@ msgstr "ir.ui.view" #. module: base #: help:res.lang,code:0 msgid "This field is used to set/get locales for user" -msgstr "Dieses Feld bestimmt die LOCAL Variable für diese Benutzer" +msgstr "" +"Mit diesem Feld wird die \"locale\" (Ländereinstellungen) des Benutzers " +"festgelegt" #. module: base #: model:res.partner.category,name:base.res_partner_category_2 @@ -12796,7 +13017,7 @@ msgid "" "Unable to install module \"%s\" because an external dependency is not met: %s" msgstr "" "Es ist nicht möglich das Modul \"%s\" zu installieren, da eine Abhängigkeit " -"nicht erfüllt werden kann: %s" +"nicht erfüllt ist: %s" #. module: base #: view:ir.module.module:0 @@ -12816,7 +13037,7 @@ msgstr "Weißrussland" #: field:ir.actions.server,name:0 #: field:ir.actions.url,name:0 msgid "Action Name" -msgstr "Aktion Bezeichnung" +msgstr "Aktionsbezeichnung" #. module: base #: model:ir.actions.act_window,help:base.action_res_users @@ -12839,7 +13060,7 @@ msgstr "Normal" #. module: base #: model:ir.module.module,shortdesc:base.module_purchase_double_validation msgid "Double Validation on Purchases" -msgstr "" +msgstr "Doppelte Kontrolle bei Bestellungen" #. module: base #: field:res.bank,street2:0 @@ -12851,7 +13072,7 @@ msgstr "Straße 2" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_update msgid "Module Update" -msgstr "Module aktualisieren" +msgstr "Modulaktualisierung" #. module: base #: code:addons/base/module/wizard/base_module_upgrade.py:95 @@ -12923,7 +13144,7 @@ msgstr "Grenada" #. module: base #: view:ir.actions.server:0 msgid "Trigger Configuration" -msgstr "Bericht konfigurieren" +msgstr "Auslösung konfigurieren" #. module: base #: view:base.language.install:0 @@ -12942,6 +13163,14 @@ msgid "" "picking and invoice. The message is triggered by the form's onchange event.\n" " " msgstr "" +"\n" +"Modul zur Auslösung von Warnungen in OpenERP-Objekten.\n" +"==================================================\n" +"\n" +"Warn-Hinweise können für Objekte, wie Verkaufsaufträge, Bestellungen,\n" +"Kommissionierungen und Rechnungen, ausgelöst werden. Die Mitteilung \n" +"wird ausgelöst durch das Onchange-Ereignis des jeweiligen Formulars.\n" +" " #. module: base #: code:addons/osv.py:150 @@ -13002,6 +13231,17 @@ msgid "" "it to all the users.\n" " " msgstr "" +"\n" +"Dieses Modul ergänzt die Funktionalität Mitteilungen aus der " +"Projektbearbeitung heraus zu versenden.\n" +"=============================================================================" +"=======\n" +"\n" +"Ein Anwender kann hiermit individuelle Mitteilungen an andere Benutzer " +"verschicken.\n" +"Es sind sogar \"Rundschreiben\" möglich, bei denen eine Mitteilung an alle " +"anderen versendet werden.\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_hr @@ -13040,6 +13280,15 @@ msgid "" "This module gives the details of the goods traded between the countries of " "European Union " msgstr "" +"\n" +"Dieses Modul fügt Intrastat-Berichte in das System ein.\n" +"===============================================\n" +"\n" +"Das Modul ergänzt Produkt-Details für den Handel zwischen Ländern \n" +"der Europäischen Union (EU) gem. der EG-Verordnung Nr. 638/2004 über \n" +"die Gemeinschaftsstatistiken des Warenverkehrs zwischen Mitgliedstaaten.\n" +"Die Abgabe dieser Meldungen ist in allen EU-Mitgliedstaaten i. d. R. " +"verbindlich. " #. module: base #: model:ir.module.module,description:base.module_stock_invoice_directly @@ -13052,6 +13301,13 @@ msgid "" "the invoicing wizard if the delivery is to be invoiced.\n" " " msgstr "" +"\n" +"Rechnungsassisten für Lieferungen.\n" +"===============================\n" +"\n" +"Wenn Sie Waren versenden oder anliefern, hilft Ihnen dieses Modul\n" +"über einen Assistenten die Lieferung in Rechnung zu stellen.\n" +" " #. module: base #: code:addons/orm.py:1388 @@ -13068,7 +13324,7 @@ msgstr "Standard" #. module: base #: view:partner.wizard.ean.check:0 msgid "Correct EAN13" -msgstr "richtige EAN13" +msgstr "Richtiger EAN13" #. module: base #: selection:res.company,paper_format:0 @@ -13114,11 +13370,28 @@ msgid "" "lines: Unit price=225, Discount=0,00, Net price=225\n" " " msgstr "" +"\n" +"Dieses Modul berechnet Rabatte für Auftrags- und Rechnungspositionen bezogen " +"auf des Partners Preisliste.\n" +"=============================================================================" +"============\n" +"\n" +"Hiermit wird eine neue Kontrollbox \"Sichtbarer Rabatt\" im Formular der " +"Preisliste hinzugefügt.\n" +"\n" +"Beispiel:\n" +" Das Produkt PC1 beim Partner Asustek: Listenpreis=450, aus der " +"Preisliste von \n" +" Asustek ergibt sich ein Preis von 225\n" +" Wenn nun die Kontrollbox aktiviert wird, erhalten wir auf dem Auftrag: \n" +" Einzelpreis=450, Rabatt=50 (%), Nettopreis=225\n" +" Mit deaktivierter Kontrollbox: Einzelpreis=Nettopreis=225, Rabatt=0.\n" +" " #. module: base #: field:ir.module.module,shortdesc:0 msgid "Short Description" -msgstr "Kurzbeschreibung" +msgstr "Kurzbezeichnung" #. module: base #: field:res.country,code:0 @@ -13148,7 +13421,7 @@ msgstr "Wähle Feldmerkmal" #. module: base #: field:res.request.history,date_sent:0 msgid "Date sent" -msgstr "Sendedatum" +msgstr "Versanddatum" #. module: base #: view:ir.sequence:0 @@ -13173,7 +13446,7 @@ msgstr "Monat: %(month)s" #: field:res.widget.user,sequence:0 #: field:wizard.ir.model.menu.create.line,sequence:0 msgid "Sequence" -msgstr "Sequenz" +msgstr "Reihenfolge" #. module: base #: model:res.country,name:base.tn @@ -13206,7 +13479,7 @@ msgstr "Entwurf und Aktiv" #: view:ir.actions.server:0 #: model:ir.ui.menu,name:base.menu_server_action msgid "Server Actions" -msgstr "Server Aktion" +msgstr "Server-Aktion" #. module: base #: field:res.partner.bank.type,format_layout:0 @@ -13242,11 +13515,26 @@ msgid "" "HR Applicant and Project Issue from selected mails.\n" " " msgstr "" +"\n" +"Dieses Modul wird für das Thunderbird-Plugin benötig, damit dieses " +"funktionieren kann.\n" +"========================================================================\n" +"\n" +"Das Plugin erlaubt Ihnen die Archivierung von EMail mitsamt Anhängen in " +"OpenERP-Objekten.\n" +"Sie können einen Partner, einer Aufgabe, ein Projekt, ein analytisches Konto " +"oder ein beliebiges \n" +"anderes Objekt in OpenERP auswählen und die gewünschte EMail als .eml-Datei " +"dem Objekt als\n" +"Anhang anfügen. Sie können aus der EMail neue Dokumente, in den Bereichen " +"Kunden-Leads,\n" +"Personal-Bewerber und Projekt-Problembearbeitung, anlegen.\n" +" " #. module: base #: view:res.lang:0 msgid "Legends for Date and Time Formats" -msgstr "Legende Datum und Zeit" +msgstr "Legende für Datum- und Zeit-Darstellungen" #. module: base #: selection:ir.actions.server,state:0 @@ -13261,7 +13549,7 @@ msgstr "Verwaltung von Emails" #. module: base #: field:ir.actions.server,trigger_name:0 msgid "Trigger Signal" -msgstr "Signalauslöser" +msgstr "Auslösesignal" #. module: base #: code:addons/base/res/res_users.py:119 @@ -13288,18 +13576,29 @@ msgid "" " * Repair quotation report\n" " * Notes for the technician and for the final customer\n" msgstr "" +"\n" +"Aufgabe dieses Moduls ist die Verwaltung von Produktreparaturen.\n" +"========================================================\n" +"\n" +"Die folgenden Aufgaben werden durch das Modul zur Verfügung gestellt:\n" +" * Zu reparierende Produkte hinzufügen und löschen\n" +" * Auswirkung auf Lagerbestände\n" +" * Rechnungsstellung (Produkte wie auch Leistung)\n" +" * Umsetzung von Garantie- und Gewährleitsungskonzepten\n" +" * Ausdruck von Reparaturangeboten\n" +" * Hinweise für den Techniker wie auch den Endkunden\n" #. module: base #: model:ir.actions.act_window,name:base.action_country_state #: model:ir.ui.menu,name:base.menu_country_state_partner msgid "Fed. States" -msgstr "Partner Regionen" +msgstr "Bundesländer / Regionen" #. module: base #: view:ir.model:0 #: view:res.groups:0 msgid "Access Rules" -msgstr "Berechtigungen Regeln" +msgstr "Zugriffsberechtigungen" #. module: base #: model:ir.module.module,description:base.module_knowledge @@ -13313,11 +13612,19 @@ msgid "" "document and Wiki based Hidden.\n" " " msgstr "" +"\n" +"Installationsmodul für versteckte, wissens-bezogene Module.\n" +"===================================================\n" +"\n" +"Macht die Konfiguration der Wissensanwendung verfügbar, über die Sie \n" +"die versteckten Module Dokument-Wissen und Wiki-Wissen installieren\n" +"können.\n" +" " #. module: base #: field:res.groups,trans_implied_ids:0 msgid "Transitively inherits" -msgstr "Vorübergehende Vererbung" +msgstr "Erbt übergangsweise" #. module: base #: field:ir.default,ref_table:0 @@ -13368,7 +13675,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_account_analytic_plans msgid "Multiple Analytic Plans" -msgstr "" +msgstr "Mehrschichtige analytische Pläne" #. module: base #: model:ir.module.module,description:base.module_project_timesheet @@ -13384,6 +13691,18 @@ msgid "" "\n" " " msgstr "" +"\n" +"Abgleich von Arbeit/Aufgaben aus Projekten mit Einträgen ausZeitnachweisen.\n" +"==================================================================\n" +"\n" +"Dieses Modul gibt Ihnen die Möglichkeit Aufgaben aus dem Projektmanagement\n" +"in Zeitnachweis-Einträge für bestimmte Mitarbeiter und an bestimmten Daten " +"zu \n" +"überführen, wobei sowohl auf Projekt- wie auch die Zeitnachweiseseite " +"effektiv \n" +"Einträge angelegt, bearbeitet und gelöscht werden können.\n" +"\n" +" " #. module: base #: view:ir.sequence:0 @@ -13417,6 +13736,20 @@ msgid "" " \n" "%(country_code)s: the code of the country" msgstr "" +"Sie können hier das übliche Format angeben, in dem Adressen dieses Landes " +"wiedergegeben werden.\n" +"\n" +"Sie können Zeichenketten im Stile von Python mit allen Feldern einer Adresse " +"verwenden \n" +"(z. B. '%(street)s' um das Feld 'street' anzuzeigen) und\n" +"\n" +"%(state_name)s für das Bundesland\n" +"\n" +"%(state_code)s für das Kürzel des Bundeslandes\n" +"\n" +"%(country_name)s für den Namen des Landes\n" +"\n" +"%(country_code)s für die Kurzform / die Kennung" #. module: base #: model:ir.module.module,description:base.module_pad @@ -13430,6 +13763,15 @@ msgid "" "(by default, http://ietherpad.com/).\n" " " msgstr "" +"\n" +"Fügt dem Web-Klienten erweiterte Unterstützung für (Ether)Pad-Zubehör " +"hinzu.\n" +"==================================================================\n" +"\n" +"Läßt das Unternehmen einstellen, welche Pad-Installation verwendet werden " +"soll,\n" +"um neue Pad-Geräte zu verbinden (Vorgabe: http://etherpad.com/).\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_uk @@ -13465,6 +13807,31 @@ msgid "" " * http://controlchaos.com\n" " " msgstr "" +"\n" +"Dieses Modul setzt alle methodischen Konzepte eines Scrum-Projekt-" +"Managements von IT-Unternehmen um.\n" +"=============================================================================" +"============\n" +"\n" +" * Projekte mit Sprints, Projektbesitzer, Scrum-Meister\n" +" * Sprints mit Prüfung, Tägliche Treffen, Rückmeldungen\n" +" * Produkt Rückblick\n" +" * Sprint Rückblick\n" +"\n" +"Es fügt einige Konzepte dem Modul Projekt-Management hinzu:\n" +" * Mittel- und Langfristige Vorausplanung (Road-Maps)\n" +" * Kunden- und Funktionale Anfragen vs. Technischer Anfragen\n" +"\n" +"Es werden auch neue Berichte ergänzt:\n" +" * Burn-Down Diagramm\n" +"\n" +"Scrum-Projekte und -Aufgaben teilen Ihre Daten mit realen Projekten,\n" +"so dass Sie wie gewohnt an normalen Aufgaben arbeiten können. Hier\n" +"werden lediglich auch Aufgaben aus Scrum-Projekten zusätzlich erscheinen.\n" +"\n" +"Mehr Information zu diesen Methoden:\n" +" http://controlchaos.com\n" +" " #. module: base #: code:addons/base/ir/ir_model.py:371 @@ -13473,8 +13840,9 @@ msgid "" "Changing the type of a column is not yet supported. Please drop it and " "create it again!" msgstr "" -"Wechsel der Datentyps eines Feldes wird nicht unterstützt. Bite brechen Sie " -"den Vorgang ab oder erstellen einen neuen Schüssel von Anfang an" +"Wechsel der Datentyps eines Feldes wird (noch) nicht unterstützt. Bitte " +"löschen Sie das Feld \r\n" +"und legen es mit gewünschtem Datentyp neu an." #. module: base #: field:ir.ui.view_sc,user_id:0 @@ -13485,7 +13853,7 @@ msgstr "Benutzer Referenz" #: code:addons/base/res/res_users.py:118 #, python-format msgid "Warning !" -msgstr "Warnung !" +msgstr "Warnung!" #. module: base #: model:res.widget,title:base.google_maps_widget @@ -13527,7 +13895,7 @@ msgstr "Guatemala Buchführung" #. module: base #: help:ir.cron,args:0 msgid "Arguments to be passed to the method, e.g. (uid,)." -msgstr "Argumente, die der Methode übergeben werden." +msgstr "Argumente, die der Methode übergeben werden, zum Bsp. (uid,)." #. module: base #: model:res.partner.category,name:base.res_partner_category_5 @@ -13569,7 +13937,7 @@ msgstr "Libanon" #: view:ir.actions.report.xml:0 #: field:ir.actions.report.xml,report_type:0 msgid "Report Type" -msgstr "Report Type" +msgstr "Berichtsart" #. module: base #: field:ir.actions.todo,state:0 @@ -13600,6 +13968,22 @@ msgid "" "in the form of pdf file. Implements a dashboard for My Current Evaluations\n" " " msgstr "" +"\n" +"Ermöglicht die Anlage von Mitarbeiter-Bewertungen-\n" +"=============================================\n" +"\n" +"Eine Bewertung kann durch einen Mitarbeiter für seine Untergebenen, \n" +"Auszubildende wie auch den eigenen Vorgesetzten angelegt werden.\n" +"Die Evaluierung verläuft nach einem Plan in dem unterschiedliche \n" +"Fragebögen angelegt werden können. Es kann dabei festgelegt werden, \n" +"welche Stufe der Mitarbeiterhierarchie bestimmte Information\n" +"ausfüllen darf / muss und schließlich wird der Vorgesetzte den\n" +"Abschluss durch Prüfung und Schlussevaluierung vornehmen.\n" +"Jede (eigene) Evaluierung kann durch die Mitarbeiter selbst in\n" +"Form eines PDF eingesehen werden.\n" +"Eine Pinnwand wird für die Mitarbeiter angelegt in dem \n" +"\"Meine aktuellen Evalierungen\" erscheinen.\n" +" " #. module: base #: selection:base.language.install,lang:0 @@ -13625,12 +14009,12 @@ msgstr "Lade offizielle Übersetzung" #. module: base #: view:res.currency:0 msgid "Miscelleanous" -msgstr "Diverses" +msgstr "Verschiedenes" #. module: base #: model:res.partner.category,name:base.res_partner_category_10 msgid "Open Source Service Company" -msgstr "Open Source Service Company" +msgstr "Open Source Dienstleistungsunternehmen" #. module: base #: selection:base.language.install,lang:0 @@ -13666,7 +14050,7 @@ msgstr "Verbindungsinformationen" #. module: base #: view:ir.attachment:0 msgid "Created" -msgstr "Erzeugt" +msgstr "Angelegt" #. module: base #: help:ir.actions.wizard,multi:0 @@ -13674,8 +14058,7 @@ msgid "" "If set to true, the wizard will not be displayed on the right toolbar of a " "form view." msgstr "" -"Wenn aktiviert, dann wird der Assistent nicht im rechten Werkzeugkasten " -"angezeigt." +"Wenn aktiviert, wird der Assistent nicht im rechten Werkzeugkasten angezeigt." #. module: base #: view:base.language.import:0 @@ -13693,8 +14076,8 @@ msgid "" "External Key/Identifier that can be used for data integration with third-" "party systems" msgstr "" -"Externer Schlüssel, der für die Datenintegration mit 3-Anbietern verwendet " -"werden kann." +"Externer Schlüssel, der für die Datenintegration mit Systemen von " +"Drittanbietern verwendet werden kann." #. module: base #: model:ir.module.module,description:base.module_mrp_operations @@ -13729,6 +14112,41 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul fügt Status, Anfangsdatum, Enddatum in Arbeitsaufträgen von " +"Fertigungsaufträgen ein\n" +"(im Fertigungsstellen-Reiter)\n" +"=============================================================================" +"========\n" +"\n" +"Status: Entwurf, Bestätigt, Erledigt, Abgebrochen\n" +"Wenn Fertigungsaufträge erledigt, bestätigt oder abgebrochen werden, werden " +"auch alle \n" +"Arbeitsaufträge entsprechenden Status erhalten.\n" +"\n" +"Angelegte, neue Menüs:\n" +"Fertigung -> FErtigung -> Arbeitsaufträge\n" +"\n" +"Dies stellt eine Sicht auf die Fertigungstellen-Positionen des bezogenen " +"Fertigungsauftrages dar.\n" +"\n" +"Es werden neue Schalter in den Formularen der Fertigungsaufträge im Reiter \n" +"Fertigungsstellen angelegt:\n" +"* Start (Status wird \"Begonnen\"), Anfangsdatum wird festgesetzt\n" +"* Erledigt (Status wird \"Erledigt\"), Enddatum wird festgelsetzt\n" +"* Entwurf (Status wird \"Entwurf\")\n" +"* Abbruch (Status wird zu \"Abgebrochen\")\n" +"\n" +"Wenn der Fertigungsauftrag \"Bereit zur Fertigung\" ist, werden " +"Arbeitsaufträge\n" +"\"Bestätigt\". Ist der Fertigungsauftrag \"Erledigt\" werden alle " +"Arbeitsaufträge \n" +"als Erledigt gesetzt.\n" +"\n" +"Das Feld Dauer stellt die Durchlaufzeit (Enddatum - Anfangsdatum) dar.\n" +"Hier kann der theoretische Durchlauf mit dem realen verglichen werden.\n" +"\n" +" " #. module: base #: model:ir.module.module,description:base.module_auction @@ -13752,6 +14170,24 @@ msgid "" " * Objects By Day (graph)\n" " " msgstr "" +"\n" +"Dieses Modul verwaltet Einträge Künstlern, Auktionsartikeln, Käufern und " +"Verkäufern.\n" +"========================================================================\n" +"\n" +"Dies ist einevollständige Verwaltung einer Auktion mit Verwaltung der " +"Gebote, \n" +"Nachverfolgung der Verkauften Artikel/Produkte zusammen mit den Zahlungen\n" +"bzw. offenen Posten und schließlich der Auslieferung der Ware.\n" +"\n" +"Die Pinnwand für Auktionen schließt ein:\n" +" * Liste der zuletzt eingestellten Objekte,\n" +" * Liste der letzten Gebote,\n" +" * Liste der Objektkennzahlen,\n" +" * Diagramm der Zuschlagssummen,\n" +" * Diagramm Min./Zuschl/Max. -Verlauf\n" +" * Diagramm Tagesverkaufszahlen nach Tagen\n" +" " #. module: base #: model:ir.module.module,description:base.module_base_crypt @@ -13797,7 +14233,7 @@ msgstr "Ansicht Referenz" #. module: base #: model:ir.module.category,description:base.module_category_sales_management msgid "Helps you handle your quotations, sale orders and invoicing." -msgstr "Erstellen Sie Angebote, Aufträge und Rechnungen." +msgstr "Unterstützt Sie bei Ihren Angeboten, Aufträgen und Rechnungen." #. module: base #: field:res.groups,implied_ids:0 @@ -13826,7 +14262,7 @@ msgstr "Icon URL" #: field:ir.actions.url,type:0 #: field:ir.actions.wizard,type:0 msgid "Action Type" -msgstr "Aktion" +msgstr "Aktionart" #. module: base #: model:res.country,name:base.vn @@ -13847,6 +14283,16 @@ msgid "" "Chad, Togo.\n" " " msgstr "" +"Dieses Modul setzt die Buchhaltung für Länder der OHADA-Region um.\n" +" Es ermöglich einem Unternehmen oder Konzern die eigene Finanzbuchhaltung " +"zu verwalten.\n" +" Länder, die OHADA-Buchhaltung verwenden sind:\n" +" Benin, Burkina Faso, Kamerun, Zentral-Afrikanische Republik, Komoros, " +"Kongo,\n" +" Elfenbeinküste, Gabun, Guinea, Guinea Bissau, Äquatorial Guinea, Mali, " +"Niger,\n" +" Demokratische Republik Kongo, Senegal, Tschad, Togo.\n" +" " #. module: base #: view:base.language.import:0 @@ -13858,7 +14304,7 @@ msgstr "Importiere Übersetzung" #. module: base #: field:res.partner.bank.type,field_ids:0 msgid "Type fields" -msgstr "Felder Typen" +msgstr "Typfelder" #. module: base #: view:ir.actions.todo:0 @@ -13950,6 +14396,15 @@ msgid "" "you can modify in OpenOffice. Once you have modified it you can\n" "upload the report using the same wizard.\n" msgstr "" +"\n" +"Dieses Modul wird zusammen mit dem OpenERP OpenOffice-Plugin verwendet.\n" +"==================================================================\n" +"\n" +"Dieses Modul fügt dem System einen Assistenten hinzu mit dem .SXW Berichte\n" +"nach OpenOffice Im- bzw. Exportiert werden und dort verändert werden " +"können.\n" +"Die angepaßten Berichte können über den gleichen Assistenten wieder in das \n" +"OpenERP-Berichtssystem hochgeladen werden.\n" #. module: base #: view:ir.sequence:0 @@ -13964,7 +14419,7 @@ msgstr "Entferne Haken, um den Kontakt in der Ansicht zu verstecken" #. module: base #: model:ir.model,name:base.model_res_widget_wizard msgid "Add a widget for User" -msgstr "Assistent hinzufügen für Benutzer" +msgstr "Hinzufügen eines Anzeigeelements" #. module: base #: model:res.country,name:base.dk @@ -13987,6 +14442,19 @@ msgid "" "If you need to manage your meetings, you should install the CRM module.\n" " " msgstr "" +"\n" +"Dies ist ein Vollwertiges Kalendersystem.\n" +"==================================\n" +"\n" +"Es unterstützt:\n" +" - Veranstaltungskalender\n" +" - Alarme (Anlegen von Anfragen)\n" +" - Wiederkehrende Termine\n" +" - Einladungen an Personen\n" +"\n" +"Wenn Sie Ihre (Zusammen-) Treffen verwalten müssen, sollten Sie die \n" +"Kundenverwaltung (CRM) installieren.\n" +" " #. module: base #: view:ir.rule:0 @@ -14002,7 +14470,7 @@ msgstr "workflow.instance" #: code:addons/orm.py:471 #, python-format msgid "Unknown attribute %s in %s " -msgstr "Unbekannte Attribute %s in %s " +msgstr "Unbekanntes Attribut %s in %s " #. module: base #: view:res.lang:0 @@ -14018,7 +14486,7 @@ msgstr "nicht definierte 'get' Funktion" #. module: base #: selection:base.language.install,lang:0 msgid "Norwegian Bokmål / Norsk bokmål" -msgstr "Norwegian Bokmål / Norsk bokmål" +msgstr "Norwegische Buchhaltung" #. module: base #: model:res.partner.title,name:base.res_partner_title_madam @@ -14049,17 +14517,17 @@ msgstr "Lohnbuchhaltung" #. module: base #: help:ir.attachment,type:0 msgid "Binary File or external URL" -msgstr "Binäres Feld oder externe URL" +msgstr "Binäre Datei oder externe URL" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_order_dates msgid "Dates on Sales Order" -msgstr "" +msgstr "Daten auf Verkaufsaufträgen" #. module: base #: view:ir.attachment:0 msgid "Creation Month" -msgstr "Monat Erstellung" +msgstr "Erstellungsmonat" #. module: base #: model:res.country,name:base.nl @@ -14081,11 +14549,22 @@ msgid "" "technical OpenERP documentation at http://doc.openerp.com\n" " " msgstr "" +"\n" +"Stellt eine allgemeine EDI-Schnittstelle für andere Module zur Verfügung\n" +"============================================================\n" +"\n" +"OpenERP stellt ein allg. EDI-Format zur Verfügung um Geschäftdokumente \n" +"mit anderen Anwendungen auszutauschen und stellt hierfür generelle\n" +"Mechanismen für Import und Export bereit.\n" +"\n" +"Weitere Details über das in OpenERP verwendete EDI-Format erhalten Sie \n" +"in der technischen Dokumentation unter http://doc.openerp.com\n" +" " #. module: base #: model:ir.ui.menu,name:base.next_id_4 msgid "Low Level Objects" -msgstr "Detailebene Objekte" +msgstr "Objekte auf Detailebene" #. module: base #: help:ir.values,model:0 @@ -14095,7 +14574,7 @@ msgstr "Modell für das dieser Eintrag gilt" #. module: base #: field:res.country,address_format:0 msgid "Address Format" -msgstr "Adressen Format" +msgstr "Adressenformat" #. module: base #: model:ir.model,name:base.model_ir_values @@ -14119,7 +14598,7 @@ msgid "" "Here is what we got instead:\n" " %s" msgstr "" -"Hier sehen Sie was wir anstelle bekommen haben:\n" +"Hier sehen Sie, was wir an Stelle dessen bekommen haben:\n" " %s" #. module: base @@ -14132,7 +14611,7 @@ msgstr "Externe Identifikationen" #. module: base #: model:res.groups,name:base.group_sale_salesman msgid "User - Own Leads Only" -msgstr "" +msgstr "Nur eigene Leads" #. module: base #: model:res.country,name:base.cd @@ -14142,14 +14621,14 @@ msgstr "Demokratische Republik Kongo" #. module: base #: selection:base.language.install,lang:0 msgid "Malayalam / മലയാളം" -msgstr "Malayalam / മലയാളം" +msgstr "Malaysisch / മലയാളം" #. module: base #: view:res.request:0 #: field:res.request,body:0 #: field:res.request.history,req_id:0 msgid "Request" -msgstr "Anforderung" +msgstr "Anfrage" #. module: base #: model:ir.actions.act_window,help:base.act_ir_actions_todo_form @@ -14165,7 +14644,7 @@ msgstr "" #. module: base #: view:res.company:0 msgid "Portrait" -msgstr "Porträt" +msgstr "Hochformat" #. module: base #: field:ir.cron,numbercall:0 @@ -14182,7 +14661,7 @@ msgstr "Bank" #: view:base.module.upgrade:0 #: field:base.module.upgrade,module_info:0 msgid "Modules to update" -msgstr "Module Updates" +msgstr "Zu aktualisierende Module" #. module: base #: help:ir.actions.server,sequence:0 @@ -14190,13 +14669,13 @@ msgid "" "Important when you deal with multiple actions, the execution order will be " "decided based on this, low number is higher priority." msgstr "" -"Wichtig für mehrere Aktionen. Die Reihenfolge der Ausführung erfolgt nach " -"aufsteigenden Nummern." +"Wichtig beim Umgang mit mehreren Aktionen. Die Reihenfolge der Ausführung " +"erfolgt nach aufsteigenden Nummern." #. module: base #: field:ir.actions.report.xml,header:0 msgid "Add RML header" -msgstr "Hinzu RML header" +msgstr "Füge RML header ein" #. module: base #: model:ir.module.module,description:base.module_l10n_tr @@ -14211,6 +14690,16 @@ msgid "" "hesap bilgileriniz,ilgili para birimi gibi bilgiler isteyecek.\n" " " msgstr "" +"\n" +"Türkische Buchhaltung...\n" +"Türkiye için Tek düzen hesap planı şablonu OpenERP Modülü.\n" +"=============================================================================" +"=\n" +"\n" +"Bu modül kurulduktan sonra, Muhasebe yapılandırma sihirbazı çalışır\n" +"* Sihirbaz sizden hesap planı şablonu, planın kurulacağı şirket,banka hesap " +"bilgileriniz,ilgili para birimi gibi bilgiler isteyecek.\n" +" " #. module: base #: view:res.config:0 @@ -14220,12 +14709,12 @@ msgstr "Anwenden" #. module: base #: field:res.request,trigger_date:0 msgid "Trigger Date" -msgstr "Trigger Datum" +msgstr "Auslösedatum" #. module: base #: selection:base.language.install,lang:0 msgid "Croatian / hrvatski jezik" -msgstr "Croatian / hrvatski jezik" +msgstr "Kroatien / hrvatski jezik" #. module: base #: sql_constraint:res.country:0 @@ -14239,6 +14728,9 @@ msgid "" " OpenERP Web kanban view.\n" " " msgstr "" +"\n" +" OpenERP-Web-Kanbanansicht\n" +" " #. module: base #: model:ir.ui.menu,name:base.menu_project_management_time_tracking @@ -14248,13 +14740,13 @@ msgstr "Zeiterfassung" #. module: base #: view:res.partner.category:0 msgid "Partner Category" -msgstr "Partner Kategorie" +msgstr "Partnerkategorie" #. module: base #: view:ir.actions.server:0 #: selection:ir.actions.server,state:0 msgid "Trigger" -msgstr "Trigger" +msgstr "Auslöser" #. module: base #: model:ir.module.category,description:base.module_category_warehouse_management @@ -14262,8 +14754,8 @@ msgid "" "Helps you manage your inventory and main stock operations: delivery orders, " "receptions, etc." msgstr "" -"Management von Lagerorten und Verwaltung von Beständen, z.B. durch Erfassen " -"von Lieferungen, Durchführung von Inventuren, etc." +"Management Ihrer Bestände, Erfassen von Bestandsveränderungen, Durchführung " +"von Inventuren." #. module: base #: model:ir.model,name:base.model_base_module_update @@ -14368,11 +14860,92 @@ msgid "" "\n" " " msgstr "" +"\n" +"Fügt Unterstützung für eine Authentifizierung durch LDAP-Server hinzu.\n" +"============================================================\n" +"\n" +"Dieses Modul erlaubt Benutzern sich mit ihrem LDAP-Benutzernamen\n" +"und -Passwort anzumelden und legt automatisch OpenERP-Benutzer\n" +"an.\n" +"** Hinweis** Dieses Modul funktioniert nur mit Servern auf denen\n" +"das Python-LDAP-Modul installiert ist.\n" +"\n" +"Einrichtung:\n" +"++++++++++++\n" +"Nach der Installation dieses Moduls müssen Sie die LDAP-Einstellungen\n" +"im Formular LDAP der Unternehmenseinstellungen eintragen. \n" +"Verschiedene Unternehmen mögen unterschiedliche LDAP-Server\n" +"nutzen, solange sie eindeutig unterscheidbare Benutzernamen\n" +"verwenden. OpenERP erfordert, auch bei mehreren eingerichteten\n" +"Unternehmen, eindeutige Benutzer.\n" +"Anonyme LDAP-Anbindung wird ebenfalls unterstützt (sofern\n" +"die LDAP-Server dies zulassen), dabei wird einfach das Benutzer-\n" +"und Passwort-Feld der LDAP-Konfiguration jeweils leer gelassen.\n" +"Dies erlaubt **nicht** die anonyme Anmeldung durch Benutzer.\n" +"Dies ist nur für den Haupt-LDAP-Nutzerzugang über den die \n" +"Existenz eines Benutzers geprpft wird bevor er authentifiziert wird.\n" +"Die Absicherung der Verbindung mittels STARTTLS ist verfügbar\n" +"bei LDAP-Servern, die dies unterstützen. Dabei muss diese \n" +"Einstellung bei der LDAP-Konfiguration eingestellt werden.\n" +"Für weitergehende Einstellung schauen Sie bitte nach in \n" +"ldap.conf manpage :manpage:`ldap.conf(5)`.\n" +"\n" +"Sicherheitsbetrachtungen:\n" +"+++++++++++++++++++++++\n" +"Passwörter von LDAP-Nutzern werden niemals in der OpenERP-\n" +"eigenen Datenbank gespeichert, der LDAP-Server wird für\n" +"jeden Bedarf einer Authentifizierung angefragt. Damit ist\n" +"die Duplizierung von Einträgen vermieden und die Verwaltung\n" +"findet nur an einer Stelle statt.\n" +"OpenERP ist für diese Verwaltung nicht zuständig und so muss\n" +"die Änderung von Zugangsdaten (Passwort) über andere\n" +"Möglichkeiten der LDAP-Verwaltung erfolgen.\n" +"\n" +"Es ist auch möglich, neben den LDAP-Benutzern, lokale OpenERP-\n" +"Benutzer zu pflegen. Der Administrator ist ein typisches und\n" +"offensichtliches Beispiel.\n" +"\n" +"Und so funktioniert es:\n" +"* Das System versucht zunächst den Benutzer in der lokalen\n" +"OpenERP-Datenbank zu finden und zu authentifizieren,\n" +"*Schlägt dies fehl, vielleicht weil der Benutzer nicht lokal \n" +"angelegt ist, versucht das System die Authentifizierung durch \n" +"Anfrage beim LDAP-Server.\n" +"Bei Nutzung von STARTTLS während der Authentifizierung ist\n" +"die Verschlüsselung der Anfrage sichergestellt.\n" +"\n" +"Benutzer-Vorlage\n" +"+++++++++++++++\n" +"Bei der Konfiguration von LDAP in den Unternehmens-Einstellungen\n" +"ist es auch möglich eine *Benutzer-Vorlage* auszuwählen. Ist diese\n" +"eingestellt, werden die Einstellungen aus dieser Vorlage herange-\n" +"zogen, wenn sich ein LDAP-Benutzer zum ersten Mal anmeldet.\n" +"Somit ist die Voreinstellung der Standard-Gruppzugehörigkeiten\n" +"und der Menüs von Erstnutzern möglich.\n" +"\n" +"**Warnung** Wenn Sie ein Kennwort in der Benutzer-Vorlage\n" +"setzen, gilt dieses gleiche Kennwort für alle über diese Vorlage\n" +"neu angelegten Benutzer bis diese es manuell abändern.\n" +"Dieses Verhalten werden Sie in aller Regel nicht wünschen.\n" +"Ein einfacher Weg eine solchen Vorlage einzurichten ist die \n" +"einmalige Anmeldung mittels gültigem LDAP-Benutzer. OpenERP\n" +"legt dann einen leeren, lokalen Benutzer mit dem selben Namen \n" +"(und leerem Passwort) an. Sie benennen nun diesen neuen Benutzer \n" +"auf einen im LDAP nicht existierenden Benutzer um. Bei diesem \n" +"richten Sie nun die Gruppen und Menüs wunschgemäß ein.\n" +"\n" +"Interaktion mit base_crypt\n" +"+++++++++++++++++++++++++++\n" +"Das base_crypt-Modul verträgt sich mit diesem LDAP-Modul \n" +"nicht. Es wird die LDAP-Authentifizierung deaktivieren, wenn\n" +"es gleichzeitig installiert sein sollte.\n" +"\n" +" " #. module: base #: field:res.request.history,body:0 msgid "Body" -msgstr "Hauptteil Seite" +msgstr "Textkörper" #. module: base #: code:addons/base/ir/ir_mail_server.py:199 @@ -14383,7 +14956,7 @@ msgstr "Verbindungstest erfolgreich" #. module: base #: view:partner.massmail.wizard:0 msgid "Send Email" -msgstr "Send Email" +msgstr "EMail senden" #. module: base #: field:res.users,menu_id:0 @@ -14411,7 +14984,9 @@ msgstr "auswählen" msgid "" "Indicates whether this object model lives in memory only, i.e. is not " "persisted (osv.osv_memory)" -msgstr "Zeigt an, ob dieses Modell nur im Memory existiert, (osv.osv_memoy)" +msgstr "" +"Zeigt an, ob dieses Modell nur im Speicher existiert, und damit nicht " +"persistent ist (osv.osv_memoy)" #. module: base #: code:addons/base/ir/ir_mail_server.py:415 @@ -14434,6 +15009,10 @@ msgid "" "Python code to be executed if condition is met.\n" "It is a Python block that can use the same values as for the condition field" msgstr "" +"Auszuführender Python-Programmcode, für den Fall, dass die Bedingung erfüllt " +"ist.\n" +"Dies ist ein Python-Code-Block, der die gleichen Werte nutzen kann wie in " +"der Bedingungsprüfung." #. module: base #: model:ir.actions.act_window,name:base.action_partner_supplier_form @@ -14465,7 +15044,7 @@ msgstr "Gabun" #. module: base #: model:res.groups,name:base.group_multi_company msgid "Multi Companies" -msgstr "" +msgstr "Mehrteilige Unternehmen (z. B. Filialbetrieb)" #. module: base #: view:ir.model:0 @@ -14484,7 +15063,7 @@ msgstr "Grönland" #. module: base #: model:res.groups,name:base.group_sale_salesman_all_leads msgid "User - All Leads" -msgstr "" +msgstr "Benutzer - Alle Leads" #. module: base #: field:res.partner.bank,acc_number:0 @@ -14535,6 +15114,27 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul ermöglicht eine JIT-Zeitplanung für das Beschaffungswesen.\n" +"==============================================================\n" +"\n" +"Wenn Sie dieses Modul installieren, werden Sie nicht mehr die reguläre " +"Terminierung\n" +"der Beschaffung verwenden müssen. (Die Meldebestandsregeln müssen jedoch " +"immer \n" +"noch überwacht werden, z. B. einmal am Tag)\n" +"Alle Beschaffung wird spontan bearbeitet, was gelegentlich zu kleinen " +"Performance-\n" +"einbußen führen kann.\n" +"\n" +"Dies könnte auch zu einer Erhöhung der Bestände führen, da Produkte so früh " +"wie \n" +"möglich reserviert werden und die Terminierung-Zeitplanung nicht mehr\n" +"berücksichtigt wird. In diesem Fall müssen Sie auch auf Prioritäten bei der " +"\n" +"Kommissionierung verzichten.\n" +"\n" +" " #. module: base #: model:res.country,name:base.cy @@ -14546,12 +15146,12 @@ msgstr "Zypern" #: field:partner.massmail.wizard,subject:0 #: field:res.request,name:0 msgid "Subject" -msgstr "Thema" +msgstr "Betreff" #. module: base #: selection:res.currency,position:0 msgid "Before Amount" -msgstr "" +msgstr "Vorherige Menge" #. module: base #: field:res.request,act_from:0 @@ -14603,6 +15203,13 @@ msgid "" "marketing_campaign.\n" " " msgstr "" +"\n" +"Beispieldaten für das Modul \"Marketing-Kampagne\".\n" +"=============================================\n" +"\n" +"Legt für das Modul Marketingkampagne Beispieldaten an, z. B. Leads, " +"Kampagnen, Segmentierung\n" +" " #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -14617,8 +15224,8 @@ msgid "" "The Selection Options expression is must be in the [('key','Label'), ...] " "format!" msgstr "" -"Der Ausdruck für die Auswahloptionen muss in Form eines [('key','Label'), " -"...] Formats definiert sein!" +"Der Ausdruck für die Auswahloptionen muss in der Schreibweise " +"[('key','Label'), ...] vorliegen!" #. module: base #: view:ir.filters:0 @@ -14654,7 +15261,7 @@ msgid "" "workflow)" msgstr "" "Das Objekt, dass das Arbeitsfluss Signal empfangen soll (muss einen " -"definierten Arbeitsfluss haben)" +"zugeordneten Arbeitsfluss haben)" #. module: base #: model:ir.module.category,description:base.module_category_account_voucher @@ -14699,8 +15306,8 @@ msgid "" "template for a new language example)." msgstr "" "Dieser Assistent findet nicht übersetzte Begriffe, die Sie sodann manuell " -"übersetzen oder einen kompletten Export durchführen können( zB als Vorlage " -"für eine neue Sprache)" +"übersetzen oder einen kompletten Export durchführen können (z. B. als " +"Vorlage für eine neue Sprache/Übersetzung)" #. module: base #: model:ir.module.module,description:base.module_l10n_ch @@ -14770,7 +15377,7 @@ msgid "" "Expression, must be True to match\n" "use context.get or user (browse)" msgstr "" -"Der Ausdruck muss Wahr sein \n" +"Der Ausdruck muss für eine Übereinstimmung Wahr sein, \n" "verwenden Sie context.get oder user (browse)" #. module: base @@ -14781,7 +15388,8 @@ msgstr "Bulgarien" #. module: base #: view:publisher_warranty.contract.wizard:0 msgid "Publisher warranty contract successfully registered!" -msgstr "Wartungsvertrag des Herausgebers wurde erfolgreich registriert" +msgstr "" +"Gewährleistungsvertrag des Herausgebers wurde erfolgreich registriert" #. module: base #: model:res.country,name:base.ao @@ -14811,7 +15419,7 @@ msgstr "5. %y, %Y ==> 08, 2008" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_ltd msgid "ltd" -msgstr "Ltd" +msgstr "mbH" #. module: base #: field:res.log,res_id:0 @@ -14843,13 +15451,13 @@ msgstr "Iran" #: model:ir.actions.act_window,name:base.res_widget_user_act_window #: model:ir.ui.menu,name:base.menu_res_widget_user_act_window msgid "Widgets per User" -msgstr "Widgets je Benutzer" +msgstr "Anzeigeelemente je Benutzer" #. module: base #: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form #: model:ir.ui.menu,name:base.menu_publisher_warranty_contract msgid "Contracts" -msgstr "Wartungsvertrag" +msgstr "Verträge" #. module: base #: field:base.language.export,state:0 @@ -14893,6 +15501,28 @@ msgid "" "using it, otherwise it may crash.\n" " " msgstr "" +"\n" +"Ziel dieses Moduls ist die Qualitätsüberwachung von anderen Modulen.\n" +"============================================================\n" +"\n" +"Es legt einen Assistenten mit einer Liste aller Module von OpenERP an. Hier " +"können die\n" +"Module nach verschiedenen Kriterien beurteilt werden, so z. B. in Bezug auf " +"\n" +"- OpenERP-Programmier-Standards,\n" +"- Ausführungs-Geschwindigkeit, \n" +"- ...\n" +"\n" +"Dieses Modul liefert darüber hinaus einen allg. Rahmen für Ihre eigenen " +"Qualitätsprüfungen.\n" +"Für weitergehende Information können Programmierer gerne mal eine Blick in " +"die Datei\n" +"base_module_quality/README.txt werfen.\n" +"\n" +"WARNUNG: Dieses Modul kann als ZIP-Datei nicht funktionieren, Sie müssen es " +"zuvor \n" +"auspacken, sonst könnte es zu Abstürzen führen.\n" +" " #. module: base #: field:res.partner.bank,bank_name:0 @@ -14913,7 +15543,7 @@ msgstr "Irak" #: model:ir.module.category,name:base.module_category_association #: model:ir.ui.menu,name:base.menu_association msgid "Association" -msgstr "Verein" +msgstr "Verein/Gesellschaft" #. module: base #: model:ir.module.module,description:base.module_stock_no_autopicking @@ -14930,6 +15560,18 @@ msgid "" "supplier in the routing of the assembly operation.\n" " " msgstr "" +"\n" +"Dieses Modul bietet die zwischengeschaltete Kommissionierung um Rohstoffe zu " +"Fertigungsaufträgen zuzuführen.\n" +"=============================================================================" +"=================\n" +"\n" +"Ein Beispiel der Anwendung mag die Verwaltung einer Fertigung durch einen " +"Zulieferer sein (Sub-Contracting).\n" +"Um dies zu verwirklichen, wird das Fremdgefertigte Teil auf \"Ohne Auto-" +"Kommission\" gesetzt und setze die\n" +"Lieferantenadresse in das Routing der Fertigung ein.\n" +" " #. module: base #: view:ir.actions.server:0 @@ -14943,9 +15585,9 @@ msgid "" "are available. To add a new language, you can use the 'Load an Official " "Translation' wizard available from the 'Administration' menu." msgstr "" -"Die Standardsprache der Benutzerschnittstelle, wenn die entsprehcende " -"Übersetzung vorhanden ist. Mit dem Assistenen \"Lade offizielle " -"Übersetzung\" können Sie weitere Sprachen laden." +"Die Standardsprache der Benutzerschnittstelle, wenn die entsprechende " +"Übersetzungen vorhanden sind. Mit dem Assistenen \"Lade offizielle " +"Übersetzung\" können Sie weitere Sprachen hinzufügen." #. module: base #: model:ir.module.module,description:base.module_l10n_es @@ -14964,6 +15606,21 @@ msgid "" "Note: You should install the l10n_ES_account_balance_report module\n" "for yearly account reporting (balance, profit & losses).\n" msgstr "" +"\n" +"Spanische Buchhaltung (PGCE 2008)\n" +"=================================\n" +"\n" +"Legt die folgenenden Kontenrahmen an:\n" +" * Allg. spanischer Kontenrahmen 2008\n" +" * Allg. soanischer Kontenrahmen 2008 für kleine und mittlere " +"Unternehmen.\n" +"Es werden Vorlagen für Verkaufs- und Erwerbssteuern (Umsatz- und Vorsteuer) " +"eingerichtet.\n" +"Es werden die verschiedenen Steuerregularien eingerichtet\n" +"\n" +"Hinweis: Sie sollten das Modul l10n_ES_account_balance_report für " +"Jahresbilanz bzw.\n" +"Gewinn und Verlust -berechnung installieren.\n" #. module: base #: model:ir.model,name:base.model_ir_sequence_type @@ -14973,7 +15630,7 @@ msgstr "ir.sequence.type" #. module: base #: selection:base.language.export,format:0 msgid "CSV File" -msgstr "CSV Datei" +msgstr "CSV-Datei" #. module: base #: code:addons/base/res/res_company.py:154 @@ -14984,13 +15641,13 @@ msgstr "Telefon: " #. module: base #: field:res.company,account_no:0 msgid "Account No." -msgstr "Konto Nummer" +msgstr "Kontonummer" #. module: base #: code:addons/base/res/res_lang.py:187 #, python-format msgid "Base Language 'en_US' can not be deleted !" -msgstr "Basis Sprache 'en_US' kann nicht gelöscht werden !" +msgstr "Basis Sprache 'en_US' kann nicht gelöscht werden!" #. module: base #: selection:ir.model,state:0 @@ -15014,6 +15671,17 @@ msgid "" "plans.\n" " " msgstr "" +"\n" +"Das Basis-Modul für die Kostenstellen- bzw. Kostenartenartenrechnung und " +"das Bestellwesen.\n" +"=============================================================================" +"==\n" +"\n" +"Ermöglicht die Anlage mehrerer analytischer Kostenrechnungen. Diese bieten " +"Ihnen die Möglichkeit\n" +"eine Bestellposition auf mehrere Konten und Kostenrechnungen geeignet " +"aufzuteilen.\n" +" " #. module: base #: field:res.company,vat:0 @@ -15130,6 +15798,26 @@ msgid "" "state are scheduled with taking the phase's start date\n" " " msgstr "" +"\n" +"Langfristige Projekt-Verwaltung, mittels der Planung, Terminierung, " +"Ressourcenzuweisung verfolgt werden kann.\n" +"=============================================================================" +"=================\n" +"\n" +"Leistungen:\n" +" * Verwaltung großer Projekte.\n" +" * Festlegen verschiedener Projekt-Phasen.\n" +" * Phasen-Zeitplanung berechnen: Start- und Enddatum von Abschnitten " +"berechnen, die innerhalb des Projektes \n" +" im Entwurf, offen oder in Bearbeitung sind.\n" +" - Ist kein Projekt angegeben, so werden alle Entwürfe, offene oder " +"in Bearbeitung befindliche Projektphasen \n" +" terminiert.\n" +" * Aufgaben-Zeitplanung: Verwendung analog der Phasen-Zeitplanung.\n" +" * Aufgabentermine ermitteln: Alle Aufgaben im Entwurf, in Bearbeitung " +"oder Ausstehend werden auf den \n" +" Beginn der zugehörigen Projektphase abgeglichen.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.action_workflow_activity_form @@ -15147,7 +15835,7 @@ msgstr "Produkte und Preislisten" #. module: base #: field:ir.actions.act_window,auto_refresh:0 msgid "Auto-Refresh" -msgstr "Autospeicherung..." +msgstr "Automatisch aktualisieren" #. module: base #: code:addons/base/ir/ir_model.py:74 @@ -15169,7 +15857,7 @@ msgstr "Spanische Buchführung (PGCE 2008)" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_no_autopicking msgid "Picking Before Manufacturing" -msgstr "Lieferschein vor Produktion" +msgstr "Kommissionierung vor Fertigung" #. module: base #: model:res.country,name:base.wf @@ -15179,7 +15867,7 @@ msgstr "Wallis- und Futuna-Inseln" #. module: base #: help:multi_company.default,name:0 msgid "Name it to easily find a record" -msgstr "Der Datensatz kann über das Name Feld leicht gefunden werden" +msgstr "Benennen Sie den Datensatz um Ihn leichter wiederzufinden" #. module: base #: model:res.country,name:base.gr @@ -15235,7 +15923,7 @@ msgid "" "try again in a few minutes" msgstr "" "Die cron-Aufgabe wird derzeit ausgeführt und kann nicht verändert werden. " -"Versuchen Sie es in einigen Minuten wieder." +"Versuchen Sie es in einigen Minuten nochmal." #. module: base #: model:ir.module.module,description:base.module_product_expiry @@ -15252,6 +15940,17 @@ msgid "" "\n" "Used, for example, in food industries." msgstr "" +"\n" +"Verschiedene Daten zu Produkten und Fertigungslosen verfolgen.\n" +"========================================================\n" +"\n" +"Folgende Daten können hier verfolgt werden:\n" +" - Ende des Lebenszyklus\n" +" - Haltbarkeitsdatum\n" +" - Datum der Beseitigung/Entfernung\n" +" - Datum einer Warnung\n" +"\n" +"Wird z. B. in Lebensmittel-Branchen verwendet." #. module: base #: field:ir.exports.line,export_id:0 @@ -15267,7 +15966,7 @@ msgstr "Holländische Buchführung" #: field:res.bank,bic:0 #: field:res.partner.bank,bank_bic:0 msgid "Bank Identifier Code" -msgstr "Bank Identifikation" +msgstr "Bank Identifikations-Code" #. module: base #: model:res.country,name:base.tm @@ -15281,6 +15980,9 @@ msgid "" " OpenERP Web process view.\n" " " msgstr "" +"\n" +" OpenERP-Web-Prozessansicht.\n" +" " #. module: base #: model:ir.module.module,description:base.module_account_chart @@ -15293,6 +15995,9 @@ msgid "" msgstr "" "\n" "Minimalen Kontenplan entfernen.\n" +"=============================\n" +"\n" +"Deaktiviert einen minimalen Kontenplan/Kontenrahmen.\n" #. module: base #: code:addons/base/ir/ir_actions.py:653 @@ -15330,7 +16035,7 @@ msgstr "Fehler" #. module: base #: model:ir.module.module,shortdesc:base.module_base_crypt msgid "DB Password Encryption" -msgstr "" +msgstr "Datenbank-Verschlüsselung mittels Passwort" #. module: base #: help:workflow.transition,act_to:0 @@ -15340,7 +16045,7 @@ msgstr "Zielaktivität" #. module: base #: model:ir.module.module,shortdesc:base.module_account_check_writing msgid "Check writing" -msgstr "Scheck Schreibung" +msgstr "Ausstellung von Schecks" #. module: base #: model:ir.module.module,description:base.module_sale_layout @@ -15356,6 +16061,17 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul erweitert die Möglichkeiten bei der Auslegung von " +"Verkaufsaufträgen.\n" +"========================================================================\n" +"\n" +"Es bietet die Möglichkeit von\n" +" * Sortierung aller Auftragspositionen\n" +" * Hinzufügen von Titeln, Kommentaren, Zwischensummen\n" +" * Zeichnen von Trennlinien und Seitenumbrüchen\n" +"\n" +" " #. module: base #: view:base.module.update:0 @@ -15367,7 +16083,7 @@ msgstr "Aktualisieren" #. module: base #: model:ir.actions.report.xml,name:base.ir_module_reference_print msgid "Technical guide" -msgstr "Technisches Wissen" +msgstr "Technischer Leitfaden" #. module: base #: view:res.company:0 @@ -15397,17 +16113,17 @@ msgstr "Weihnachtsinseln" #. module: base #: model:ir.module.module,shortdesc:base.module_web_livechat msgid "Live Chat Support" -msgstr "Live Chat Unterstützung" +msgstr "Unterstützung für Live-Chat" #. module: base #: view:ir.actions.server:0 msgid "Other Actions Configuration" -msgstr "Andere Aktionen" +msgstr "Einstellungen für sonstige Aktionen" #. module: base #: selection:ir.module.module.dependency,state:0 msgid "Uninstallable" -msgstr "Uninstallierbar" +msgstr "Nicht installierbar" #. module: base #: model:ir.module.module,description:base.module_web_dashboard @@ -15416,6 +16132,10 @@ msgid "" " OpenERP Web dashboard view.\n" " " msgstr "" +"\n" +" Open'ERP-Web Pinnwand-Ansicht.\n" +"=================================\n" +" " #. module: base #: view:res.partner:0 @@ -15450,6 +16170,20 @@ msgid "" " * Salary Maj, ONSS, Withholding Tax, Child Allowance, ...\n" " " msgstr "" +"\n" +"Belgische Lohn- und Gehaltsabrechnung\n" +"==================================\n" +"\n" +" * Mitarbeiter-angaben\n" +" * Mitarbeiterverträge\n" +" * Reisepassgestützte Verträge\n" +" * Zulagen / Abzüge\n" +" * Einstellung von Grundlohn / Lohnerhöhungen / Nettobezüge\n" +" * Lohnbescheinigung\n" +" * Monatliche Lohnabrechnung\n" +" * Mit Urlaubsplanung integriert\n" +" * Lohn berücksichtigt: Maj, ONSS, Steuerabzüge, Kindergeld, ...\n" +" " #. module: base #: model:ir.model,name:base.model_partner_wizard_ean_check @@ -15464,7 +16198,7 @@ msgstr "Kunden" #. module: base #: sql_constraint:res.users:0 msgid "You can not have two users with the same login !" -msgstr "2 Benuzter können nicht den gleichen Login Code haben." +msgstr "Zwei Benuzter dürfen nicht den gleichen Benutzernamen verwenden!" #. module: base #: model:ir.model,name:base.model_res_request_history @@ -15474,12 +16208,12 @@ msgstr "res.request.history" #. module: base #: model:ir.model,name:base.model_multi_company_default msgid "Default multi company" -msgstr "Standard Multi Mandant" +msgstr "Standard für Mehrteilige Unternehmung" #. module: base #: view:res.request:0 msgid "Send" -msgstr "Sende" +msgstr "Versenden" #. module: base #: model:ir.module.module,description:base.module_process @@ -15495,6 +16229,16 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul zeigt die grundlegenden Prozesse der ausgewählten Module und " +"die Reihenfolge in der sie auftreten können.\n" +"=============================================================================" +"========================\n" +"\n" +"Hinweis: Dies trifft auf Module mit \"modulname_prozess_xml\" zu, so z.B. " +"für product/process/product_process_xml.\n" +"\n" +" " #. module: base #: field:res.users,menu_tips:0 @@ -15509,7 +16253,7 @@ msgstr "Quelle" #. module: base #: help:res.partner.address,partner_id:0 msgid "Keep empty for a private address, not related to partner." -msgstr "Leer nur bei Privat" +msgstr "Bei Privat-Kontakten, ohne Bezug zu Partnern, leer lassen." #. module: base #: model:res.country,name:base.vu @@ -15519,12 +16263,12 @@ msgstr "Vanuatu" #. module: base #: view:res.company:0 msgid "Internal Header/Footer" -msgstr "InternerHeader/Footer" +msgstr "Interne Kopf-/Fußzeile" #. module: base #: model:ir.module.module,shortdesc:base.module_crm msgid "CRM" -msgstr "CRM" +msgstr "Kundenverwaltung" #. module: base #: code:addons/base/module/wizard/base_export_language.py:59 @@ -15534,12 +16278,12 @@ msgid "" "may be uploaded to launchpad." msgstr "" "Speichere dieses Dokument als .tgz Datei. Dieses Archiv enthält UTF-8 %s " -"Dateien und können nach launchpad hochgeladen werden." +"Dateien und kann nach launchpad hochgeladen werden." #. module: base #: view:base.module.upgrade:0 msgid "Start configuration" -msgstr "Start Konfiguration" +msgstr "Einrichtung beginnen" #. module: base #: view:base.language.export:0 @@ -15549,7 +16293,7 @@ msgstr "_Export" #. module: base #: model:ir.module.module,shortdesc:base.module_account_followup msgid "Followup Management" -msgstr "Offene Posten Verwaltung" +msgstr "Mahnwesen" #. module: base #: model:ir.module.module,description:base.module_l10n_fr @@ -15560,6 +16304,11 @@ msgid "" "\n" "Credits: Sistheo Zeekom CrysaLEAD\n" msgstr "" +"\n" +"Dieses Modul enthält die französichen Kontenrahmen für OpenERP.\n" +"==========================================================\n" +"\n" +"Credits: Sistheo Zeekom CrysaLEAD\n" #. module: base #: selection:base.language.install,lang:0 @@ -15579,7 +16328,7 @@ msgstr "Dominikanische Republik" #. module: base #: selection:base.language.install,lang:0 msgid "Serbian (Cyrillic) / српски" -msgstr "Serbisch (Cyrillic) / српски" +msgstr "Serbisch (Kyrillisch) / српски" #. module: base #: code:addons/orm.py:2527 @@ -15588,8 +16337,8 @@ msgid "" "Invalid group_by specification: \"%s\".\n" "A group_by specification must be a list of valid fields." msgstr "" -"Fehlerhafte Spezifikation der Gruppierung: \"%s\".\n" -"Eine group_by Spezifikation sollte eine gültige Liste mit Feldern aufweisen." +"Fehlerhafte Angabe der Gruppierung: \"%s\".\n" +"Eine \"Gruppiere...\"-Angabe muss eine gültige Liste mit Feldern aufweisen." #. module: base #: selection:ir.mail_server,smtp_encryption:0 @@ -15600,7 +16349,7 @@ msgstr "TLS (STARTTLS)" #: help:ir.actions.act_window,usage:0 msgid "Used to filter menu and home actions from the user form." msgstr "" -"Wird verwendet um Menu und Startseiten des Benutzer Formulars zu filtern" +"Wird verwendet um Menu und Startseiten des Benutzer-Formulars zu filtern" #. module: base #: model:res.country,name:base.sa @@ -15611,12 +16360,12 @@ msgstr "Saudi Arabien" #: help:res.company,rml_header1:0 msgid "Appears by default on the top right corner of your printed documents." msgstr "" -"Scheint standardmäßig im oberen rechten Eck der gedruckten Berichte auf." +"Erscheint standardmäßig im oberen, rechten Eck von gedruckten Berichten." #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_crm_claim msgid "eMail Gateway for CRM Claim" -msgstr "" +msgstr "EMail-Schnittstelle für das Beschwerdemodul in der Kundenverwaltung" #. module: base #: help:res.partner,supplier:0 @@ -15625,18 +16374,19 @@ msgid "" "people will not see it when encoding a purchase order." msgstr "" "Hake diese Box an falls Ihr Partner Lieferant ist, Falls dieser Haken nicht " -"gesetzt wird, wird der Einkäufer diese Position nicht in Suchlisten finden." +"gesetzt wird, wird der Einkäufer diesen Partner bei einer Lieferantensuche " +"(Lieferanten-Auswahlfeld) nicht finden." #. module: base #: field:ir.actions.server,trigger_obj_id:0 #: field:ir.model.fields,relation_field:0 msgid "Relation Field" -msgstr "erforderliches Feld" +msgstr "Beziehungs-Feld" #. module: base #: view:res.partner.event:0 msgid "Event Logs" -msgstr "Ereignisse Aufzeichnungen" +msgstr "Ereignissprotokoll" #. module: base #: code:addons/base/module/wizard/base_module_configuration.py:38 @@ -15647,7 +16397,7 @@ msgstr "System Konfiguration erledigt" #. module: base #: view:ir.actions.server:0 msgid "Create / Write / Copy" -msgstr "Erzeugen / Schreiben / Kopieren" +msgstr "Anlegen / Schreiben / Kopieren" #. module: base #: field:workflow.triggers,instance_id:0 @@ -15658,7 +16408,7 @@ msgstr "Zielobjekt" #: field:ir.actions.act_window,multi:0 #: field:ir.actions.wizard,multi:0 msgid "Action on Multiple Doc." -msgstr "Aktion für mehrfache Dokumente" +msgstr "Aktion für mehrere Dokumente" #. module: base #: view:base.language.export:0 @@ -15673,7 +16423,7 @@ msgstr "Exportiere Übersetzungen" #. module: base #: field:ir.actions.report.xml,report_xml:0 msgid "XML path" -msgstr "XML" +msgstr "XML-Pfad" #. module: base #: help:ir.sequence,implementation:0 @@ -15682,9 +16432,9 @@ msgid "" "later is slower than the former but forbids any gap in the sequence (while " "they are possible in the former)." msgstr "" -"2 Arten von Sequenzen werden unterstützt. \r\n" -"* Standard: schneller mit Lücken.\r\n" -"* Ohne Lücken: etwas langsamer, aber erstellt lückenlose Nummerierung." +"2 Arten von Folgen werden unterstützt. \r\n" +"* Standard: Schneller jedoch mit Lücken.\r\n" +"* Ohne Lücken: Etwas langsamer, erstellt aber lückenlose Nummerierung." #. module: base #: model:res.country,name:base.gn @@ -15762,6 +16512,16 @@ msgid "" "After installing the module, it adds a menu to define a custom report in\n" "the Administration / Customization / Reporting menu.\n" msgstr "" +"\n" +"Dieses Modul ermöglich die Erstellung von Statistiken zu verschiedenen " +"Objekten.\n" +"====================================================================\n" +"\n" +"Es ist ein SQL-Abfrage-Werkzeug mit Datenanzeige für Endanwender.\n" +"\n" +"Nach der Installation des Moduls wird ein Menüpunkt in\n" +"Einstellungen / Personalisierung / Berichtswesen\n" +"mit der Bezeichnung \"Individuelle Berichte\" hinzugefügt.\n" #. module: base #: model:ir.module.module,shortdesc:base.module_report_designer @@ -15796,16 +16556,19 @@ msgid "" " OpenERP Web calendar view.\n" " " msgstr "" +"\n" +" OpenERP-Web-Kalenderformular.\n" +" " #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_lead msgid "Leads & Opportunities" -msgstr "Kontakte und Chancen" +msgstr "Leads und Chancen" #. module: base #: selection:base.language.install,lang:0 msgid "Romanian / română" -msgstr "Romanian / română" +msgstr "Romänisch / română" #. module: base #: view:res.log:0 @@ -15822,7 +16585,7 @@ msgstr "und" #: help:ir.values,res_id:0 msgid "" "Database identifier of the record to which this applies. 0 = for all records" -msgstr "" +msgstr "Kennung des Datensatzes auf den dies zutrifft. 0 = alle Datensatze" #. module: base #: field:ir.model.fields,relation:0 @@ -15854,7 +16617,7 @@ msgstr "ir.actions.act_window" #. module: base #: field:ir.rule,perm_create:0 msgid "Apply For Create" -msgstr "Setze Erzeugungsberechtigung" +msgstr "Anwenden zur Anlage" #. module: base #: model:res.country,name:base.vi @@ -15875,7 +16638,7 @@ msgstr "Wechselkurs" #: field:workflow,osv:0 #: field:workflow.instance,res_type:0 msgid "Resource Object" -msgstr "Ressource Object" +msgstr "Ressourcen-Objekt" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_helpdesk @@ -15899,7 +16662,7 @@ msgstr "" #. module: base #: field:ir.ui.view,field_parent:0 msgid "Child Field" -msgstr "(Unter-) Konto" +msgstr "(Unter-) Feld" #. module: base #: view:ir.rule:0 @@ -15933,8 +16696,8 @@ msgid "" "Lets you install various interesting but non-essential tools like Survey, " "Lunch and Ideas box." msgstr "" -"Optionale Erweiterung interessanter, aber nicht zwingend zu installierender " -"Applikationen, wie z.B. Umfragen, Vorschlagswesen etc." +"Optionale Erweiterung interessanter, aber nicht notwendiger Module, wie z.B. " +"Umfragen, Vorschlagswesen etc." #. module: base #: selection:ir.module.module,state:0 @@ -15965,6 +16728,28 @@ msgid "" "Print product labels with barcode.\n" " " msgstr "" +"\n" +"Dies ist das Grundmodul für die Verwaltung von Produkten und Preislisten in " +"OpenERP.\n" +"========================================================================\n" +"\n" +"Produkte können Varianten haben, verschieden Preisgestaltungen besitzen, " +"Lieferanten-\n" +"Information erhalten, Beschaffungsdetails, Maßeinheiten, Verpackungen und " +"andere\n" +"Eigenschaften zugewiesen bekommen.\n" +"\n" +"Preislisten unterstützen:\n" +" * Mehrstufige Rabatte (nach Produktn Kategorie, Menge)\n" +" * Preisberechnung beruht auf versch. Kriterien:\n" +" - Andere Preisliste,\n" +" - Anschaffungskosten,\n" +" - Listen-/Katalog-Preis,\n" +" - Lieferantenpreis, ...\n" +"\n" +"Preislisten-Einstellungen je Produkt und Partner,\n" +"Ettikettendruck mitsamt Barcode (Strichcode).\n" +" " #. module: base #: report:ir.module.reference.graph:0 @@ -15974,7 +16759,7 @@ msgstr "Sicht :" #. module: base #: field:ir.model.fields,view_load:0 msgid "View Auto-Load" -msgstr "Ansicht Autorefresh" +msgstr "Autom. Öffnen des Ansichtsformulars" #. module: base #: code:addons/base/ir/ir_model.py:264 @@ -16006,12 +16791,12 @@ msgstr "Web Icon Datei" #: view:base.module.upgrade:0 #: model:ir.ui.menu,name:base.menu_view_base_module_upgrade msgid "Apply Scheduled Upgrades" -msgstr "Starte Installation" +msgstr "Starte geplante Aktualsierungen" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_journal msgid "Invoicing Journals" -msgstr "Eingangsrechnungsjournale" +msgstr "Rechnungsbericht" #. module: base #: selection:base.language.install,lang:0 @@ -16035,7 +16820,7 @@ msgid "" "Supported file formats: *.csv (Comma-separated values) or *.po (GetText " "Portable Objects)" msgstr "" -"Unterstützte Dateiformate: *.csv (Comma-separated values) or *.po (GetText " +"Unterstützte Dateiformate: *.csv (Comma-separated values) oder *.po (GetText " "Portable Objects)" #. module: base @@ -16046,7 +16831,7 @@ msgid "" "these groups: %s." msgstr "" "Sie können diesen Beleg (%s) nicht löschen. Stellen Sie sicher, dass Sie als " -"Benutzer der folgenden Gruppe angehören: %s." +"Benutzer einer der folgenden Gruppen angehören: %s." #. module: base #: model:ir.module.module,description:base.module_web_livechat @@ -16058,6 +16843,12 @@ msgid "" "Add \"Support\" button in header from where you can access OpenERP Support.\n" " " msgstr "" +"\n" +"Bietet Unterstzung für Live-Chat für Vertragnehmer mit Wartungsvertrag.\n" +"\n" +"Fügt den \"Support\"-Schalter in den Kopf ein, über den Sie OpenERP-" +"Unterstützung erhalten.\n" +" " #. module: base #: model:ir.model,name:base.model_base_module_configuration @@ -16072,6 +16863,10 @@ msgid "" " This module provides the core of the OpenERP web client.\n" " " msgstr "" +"\n" +" OpenERP-Web-Kernmodul.\n" +" Dieses Modul liefert die Hauptbestandteile des OpenERP-Web-Klienten.\n" +" " #. module: base #: sql_constraint:res.country:0 @@ -16082,7 +16877,7 @@ msgstr "Der Name des Landes muss eindeutig sein!" #: field:base.language.export,name:0 #: field:ir.attachment,datas_fname:0 msgid "Filename" -msgstr "Dateinamen" +msgstr "Dateiname" #. module: base #: field:ir.model,access_ids:0 @@ -16098,7 +16893,7 @@ msgstr "Slowakische Republik" #. module: base #: model:ir.ui.menu,name:base.publisher_warranty msgid "Publisher Warranty" -msgstr "Wartungsvertrag" +msgstr "Gewährleistung des Herausgebers" #. module: base #: model:res.country,name:base.aw @@ -16129,11 +16924,24 @@ msgid "" "and decide on their status as they evolve.\n" " " msgstr "" +"\n" +"Dieses Modul stellt eine Projektverwaltung für Probleme/Fehler zur " +"Verfügung.\n" +"==================================================================\n" +"\n" +"OpenERP ermöglicht die Verwaltung von in Projekten möglicherweise " +"aufkommenden\n" +"Problemen, wie z. B. Systemfehler, Beschwerden oder Materialfehler. Eine " +"Listenansicht\n" +"erlaubt dem Verwalter die Fälle zu sichten, diese zuzuweisen und über deren " +"Status\n" +"im Laufe der Entwicklung zu wachen und daraus Entscheidungen zu treffen.\n" +" " #. module: base #: field:res.groups,full_name:0 msgid "Group Name" -msgstr "Gruppe Bezeichnung" +msgstr "Gruppenbezeichnung" #. module: base #: model:res.country,name:base.bh @@ -16195,7 +17003,7 @@ msgstr "" #. module: base #: view:res.partner.address:0 msgid "Search Contact" -msgstr "Suche Kontakt" +msgstr "Suche Ansprechpartner" #. module: base #: view:ir.attachment:0 @@ -16238,7 +17046,7 @@ msgstr "Wartungsvertrag des Herausgebers" #. module: base #: selection:base.language.install,lang:0 msgid "Bulgarian / български език" -msgstr "Bulgarian / български език" +msgstr "Bulgarisch / български език" #. module: base #: model:ir.ui.menu,name:base.menu_aftersale @@ -16258,7 +17066,7 @@ msgstr "Ausführen" #. module: base #: model:ir.module.module,shortdesc:base.module_caldav msgid "Share Calendar using CalDAV" -msgstr "Kalender mit CalDAV freigeben" +msgstr "Kalender mit CalDAV veröffentlichen" #. module: base #: field:ir.actions.act_window,limit:0 @@ -16270,8 +17078,7 @@ msgstr "Limit" msgid "" "The group that a user must have to be authorized to validate this transition." msgstr "" -"Die Gruppe der ein Benutzer angehören muss, um diese Transition zu " -"validieren." +"Die Gruppe der ein Benutzer angehören muss, um diesen Ablauf zu genehmigen." #. module: base #: code:addons/orm.py:791 @@ -16288,7 +17095,7 @@ msgstr "Jamaika" #: field:res.partner,color:0 #: field:res.partner.address,color:0 msgid "Color Index" -msgstr "Farb Index" +msgstr "Farbkennzeichnung" #. module: base #: model:ir.actions.act_window,help:base.action_partner_category_form @@ -16298,11 +17105,11 @@ msgid "" "categories have a hierarchy structure: a partner belonging to a category " "also belong to his parent category." msgstr "" -"Verwaltung der Partner Kategorien, um eine bessere Klassifizierung für die " -"Verfolgung von Vorgängen und zu Analyse und Suchzwecken zu ermöglichen. Ein " -"Partner kann dabei mehreren Kategorien zugewiesen werden. Kategorien haben " -"üblicherweise auch eine hierachische Struktur. Dabei gilt, daß eine direkt " -"zugeordnete Kategorie i.d.R. auch selbst einer Hauptkategorie zugeordnet ist." +"Verwaltung der Partnerkategorien, um eine Klassifizierung für die Verfolgung " +"von Vorgängen, Analysezwecke und Suche zu vereinfachen. Ein Partner kann " +"dabei mehreren Kategorien zugewiesen werden. Kategorien haben üblicherweise " +"auch eine hierachische Struktur. Dabei folgt aus einer Zugeordnung zu einer " +"Kategorie auch die Zuordnung zu übergeordneten Kategorien." #. module: base #: model:res.country,name:base.az @@ -16319,7 +17126,7 @@ msgstr "Warnung" #. module: base #: model:ir.module.module,shortdesc:base.module_edi msgid "Electronic Data Interchange (EDI)" -msgstr "" +msgstr "Elektronischer Datenaustausch (EDI)" #. module: base #: model:ir.module.category,name:base.module_category_tools @@ -16388,16 +17195,57 @@ msgid "" "\n" " " msgstr "" +"\n" +"EMail-Vorlagen (vereinfachte Version des Originals \"Power Email\" von " +"Openlabs)\n" +"==================================================================\n" +"\n" +"Läßt Sie vollständige EMail-Vorlagen in Bezug auf jedes OpenERP-Dokument " +"(Verkaufaufträge,\n" +"Rechnungen, ...) inklusive Versender, Empfänger, Thema Textkörper (HTML wie " +"auch Normaltext).\n" +" Sie können auch automatisch Dateien an die daraus erstellten Dokumente " +"anhängen lassen.\n" +"\n" +"Bei fortgeschrittener Anwendung können die Vorlagen auch dynamische " +"Dokumentattribute \n" +"enthalten. Zum Beispiel können Sie den Landesnamen des Partners einsetzen, " +"wenn dieser \n" +"angeschrieben wird, zugleich eine Vorgabe angebend falls diese Angabe mal " +"nicht vorliegt.\n" +"Jede Vorlage hat einen Assistenten, der Ihnen beim Einsatz dieser " +"dynamischen Werte \n" +"bei Seite steht.\n" +"\n" +"Wenn Sie diese Option einschalten, der Zusammenstellungs-Assistent auch in " +"der Seitenleiste\n" +"erscheinen, wenn aus dieser Vorlage erstellte Dokumente geöffnet sind. Somit " +"kann schnell \n" +"auch eine Vorlagenbasierte EMail ggf. nach Prüfung und Anpassung erstellt " +"und versandt \n" +"werden. Dieser Kompositions-Assistent kann auch zu einem Massen-Mail-System " +"verwandelt\n" +"werden, wenn er auf mehrere Dokumente zugleich angewandt wird.\n" +"\n" +"Diese EMail-Vorlagen sind auch das Herz des Marketing-Kampagnen-Systems " +"(siehe dort),\n" +"sofern Sie Dokumenten-spezifisch größere Kampagnen automatisieren müssen.\n" +"\n" +"Technischer Hinweis: Es wurde nur das Vorlagen-System des Originals \"Power-" +"EMail\" \n" +"von Openlabs übernommen.\n" +"\n" +" " #. module: base #: selection:base.language.install,lang:0 msgid "Czech / Čeština" -msgstr "Czech / Čeština" +msgstr "Tschechisch / Čeština" #. module: base #: model:ir.module.category,name:base.module_category_generic_modules msgid "Generic Modules" -msgstr "Generische Module" +msgstr "Allgemeine Module" #. module: base #: model:ir.actions.act_window,help:base.action_partner_supplier_form @@ -16407,8 +17255,8 @@ msgid "" "uncheck the 'Suppliers' filter button in order to search in all your " "partners, including customers and prospects." msgstr "" -"Alle Lieferantendaten können in dem Lieferantenformular bearbeitet " -"werden.(FiBu, Mails, Meetings, Einkäufe,...). Nach Deaktivierung des " +"Alle Lieferantendaten können in dem Lieferantenformular bearbeitet werden. " +"(FiBu, Mails, Termine, Einkäufe,...). Nach Deaktivierung des " "Lieferantenfilters werden alle Partner angezeigt." #. module: base @@ -16435,17 +17283,35 @@ msgid "" "to set up a management by affair.\n" " " msgstr "" +"\n" +"Dieses Modul setzt ein Zeitnachweis-System um.\n" +"========================================\n" +"\n" +"Jeder Mitarbeiter kann in verschiedenen Projekten eingebrachte Zeit " +"einpflegen und verfolgen.\n" +"Einem Projekt entspricht dabei ein analytisches Konto, eingesetzte Zeit " +"verursacht nun Projekt-\n" +"kosten die auf dieses analytische Konto verbucht werden.\n" +"\n" +"Einige Berichte und Auswertungen zur Zeiten und Mitarbeitern werden " +"verfügbar gemacht.\n" +"\n" +"Es ist vollständig integriert in die \"Kostenstellenrechnung\" und ermöglich " +"den Ansatz der\n" +"Projektbezogenen Kostenverwaltung.\n" +" " #. module: base #: help:ir.mail_server,smtp_port:0 msgid "SMTP Port. Usually 465 for SSL, and 25 or 587 for other cases." msgstr "" -"SMTP Port. normalerweise 465 für SSL, und 25 oder 587 für alle anderen." +"SMTP Port. Normalerweise 465 für SSL, und 25 oder 587 in allen anderen " +"Fällen." #. module: base #: view:ir.sequence:0 msgid "Day of the week (0:Monday): %(weekday)s" -msgstr "Tag der Woche (0:Monday): %(weekday)s" +msgstr "Wochentag (0:Monday): %(weekday)s" #. module: base #: model:res.country,name:base.ck @@ -16508,6 +17374,45 @@ msgid "" " * Opportunities by Stage (graph)\n" " * Planned Revenue by Stage and User (graph)\n" msgstr "" +"\n" +"Das allgemeine Kundenverwaltungsmodul (CRM) von OpenERP.\n" +"=====================================================\n" +"\n" +"Dieses System ermöglicht einer Gruppe von Menschen (Mitarbeiter, Abteilung) " +"die\n" +"intilligente, effiziente Verwaltung von Vorverhandlungen (Leads), " +"Gelegenheiten\n" +"(opportunities), Terminen (meeting), Anrufen (phonecall), ...\n" +"Es werden Hauptaufgaben, wie z. B. Kommunikation, Erfassung, Pririsierung,\n" +"Zuständigkeit, Problemklärung und Mitteilungsdienste umgesetzt.\n" +"\n" +"OpenERP stellt dabei sicher, dass alle Fälle durch Benutzer, Kunden und " +"Lieferanten\n" +"erfolgreich nachvollzogen werden können. Es werden automatisch Erinnerungen\n" +"verschickt, Anfragen werden eskaliert (an Vorgesetzte hoch-delegiert), " +"besondere \n" +"Aufgaben und Methoden ausgelöst und viele andere Aktionen, die auch von " +"Ihren\n" +"Unternehmensregeln abhängen, ausgelöst.\n" +"\n" +"Das schönste an diesem System ist die Tatsache, dass der Anwender nicht " +"besonderes \n" +"tun muss. Dieser sendet nur eine EMail an die Anfrageverfolgung. OpenERP " +"kümmert\n" +"sich um eine dankende Antwort und die automatische Weiterleitung an das " +"richtige \n" +"Personal. Das System stellt darüber hinaus sicher, dass auch künftiger " +"Schriftverkehr\n" +"an den richtigen Empfänger gelangt.\n" +"\n" +"Das Kundenverwaltungsmodul enthält eine EMail-Schnittstelle zur " +"Synchrnonisierung\n" +"von empfangenen Mails mit OpenERP.\n" +"\n" +"Es wird eine Pinnwand der Kundenverwaltung angelegt. Sie enthält:\n" +" * Gelegenheiten nach Kategorie (Diagramm)\n" +" * Gelegenheiten nach Entwicklungsstand (Diagramm)\n" +" * Plan-Umsätze nach Entwicklung und Bearbeiter (Diagramm)\n" #. module: base #: model:ir.module.category,description:base.module_category_accounting_and_finance @@ -16515,6 +17420,10 @@ msgid "" "Helps you handle your accounting needs, if you are not an accountant, we " "suggest you to install only the Invoicing." msgstr "" +"Unterstützt Sie bei Ihrem Bedarf an Finanzbuchhaltung. Sind Sie kein " +"Buchhalten, so empfehlen wir Ihnen\r\n" +"(sofern wegen anderer Abhängigkeiten möglich) nur das Rechnungswesen zu " +"installieren." #. module: base #: model:ir.module.module,shortdesc:base.module_plugin_thunderbird @@ -16551,11 +17460,14 @@ msgid "" " OpenERP Web test suite.\n" " " msgstr "" +"\n" +" OpenERP-Web Testanwendungen.\n" +" " #. module: base #: view:ir.values:0 msgid "Action Bindings/Defaults" -msgstr "Aktion Bindungen / Standardwerte" +msgstr "Aktionen-Bindungen / -Standardwerte" #. module: base #: view:ir.rule:0 @@ -16563,8 +17475,8 @@ msgid "" "1. Global rules are combined together with a logical AND operator, and with " "the result of the following steps" msgstr "" -"1. Allgemeine Regeln werden mit logisch UND verknüpft und dann mit den " -"Ergebnissen der folgenden Schritte" +"1. Globale Regeln werden untereinander und mit den Ergebnissen der folgenden " +"Schritte logisch UND-verknüpft" #. module: base #: view:res.partner:0 @@ -16585,7 +17497,7 @@ msgstr "Gruppen auswählen" #. module: base #: view:res.lang:0 msgid "%X - Appropriate time representation." -msgstr "%X - Erwartete Zeitpräsentation." +msgstr "%X - Angebrachte Zeitpräsentation." #. module: base #: selection:base.language.install,lang:0 @@ -16600,11 +17512,10 @@ msgid "" "1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as " "106,500. Provided ',' as the thousand separator in each case." msgstr "" -"Das Trennzeichenformat sollte sein wie [,n] wenn 0 < n :startend von " -"Einheitenziffer.-1 wird die Trennung anzeigen. Z.B. [3,2,-1] wird " -"repräsentiert 106500 muss sein1,06,500;[1,2,-1] will represent it to be " -"106,50,0;[3] will represent it as 106,500. Provided ',' as the thousand " -"separator in each case." +"Das Trennzeichenformat sollte [,n] entsprechen mit 0 < n, beginnenend bei " +"Einer-Stelle. -1 beendet die Trennung. Z. B. [3,2,-1] bei 106500 entspricht " +"1,06,500; [1,2,-1] würde dann 106,50,0 ergeben; [3] wird 106,500 daraus " +"erstellen. Vorausgesetzt ',' sei jeweils der Tausender-Trenner." #. module: base #: field:ir.module.module,auto_install:0 @@ -16620,12 +17531,12 @@ msgstr "Japan" #: code:addons/base/ir/ir_model.py:357 #, python-format msgid "Can only rename one column at a time!" -msgstr "Es kann lediglich eine Spalte gleichzeitig umbenannt werden!" +msgstr "Es kann jeweils nur eine Spalte umbenannt werden!" #. module: base #: selection:ir.translation,type:0 msgid "Wizard Button" -msgstr "Assistent Button" +msgstr "Assistent-Taste" #. module: base #: selection:ir.translation,type:0 @@ -16661,13 +17572,51 @@ msgid "" "Leads.\n" " " msgstr "" +"\n" +"Dieses Modul stellt Automatismen für Lead-Managent aus Marketingmassnahmen " +"zur Verfügung. \n" +"=============================================================================" +"====\n" +"\n" +"(Tatsächlich können Kampagnen auf jeder Ressource aufgebaut werden, nicht " +"nur an Kundenbeziehungen) \n" +"\n" +"Kampagnen sind dynamisch und Mehrspurig. Die Durchführung sieht " +"folgendermassen aus:\n" +" * Entwerfen Sie Marketingkampagnen wie Arbeitsabläufe, einschl. EMail-" +"Vorlagen zum Versenden,\n" +" Berichte zum Versenden per EMail und zum Drucken, Individuelle " +"Aktionen, ...\n" +" * Festlegen der Eingangs-Segmentierung, die den Zugang der Ressource in " +"die Kampagne steuert\n" +" (z. B. potentielle Kunden aus bestimmten Ländern, ...)\n" +" * Lassen Sie die Kampagne als Simulation laufen, testen Sie diese in " +"Echtzeit oder im Schnelldurchlauf\n" +" und treffen Sie Maßnahmen für eine Feinabstimmung.\n" +" * Sie können die tatsächliche Kampagne auch im Handbetrieb starten, bei " +"dem jeder Schritt einzeln \n" +" bestätigt (freigegeben) werden muss.\n" +" * Schließlich starten Sie Ihre Kampagne und beobachten die Statistiken " +"während die Kampagne alles\n" +" voll-automatisch durchführt.\n" +"\n" +"Auch während einer laufenden Kampagne können Sie selbstverständlich noch " +"Feinabstimmung vornehmen,\n" +"die Zugangs-Segmente verändern und Abläufe anpassen...\n" +"\n" +"Hinweis: Sollten Sie Beispieldaten benötigen, können Sie auf das " +"\"marketing_campaign_crm_demo_module\" \n" +"zurückgreifen; diese Beispieldaten hängen jedoch auch vom Kunden-Modul wie " +"auch der Leads-Verwaltung\n" +"ab und installieren diese ggf. auch.\n" +" " #. module: base #: selection:ir.actions.act_window.view,view_mode:0 #: selection:ir.ui.view,type:0 #: selection:wizard.ir.model.menu.create.line,view_type:0 msgid "Graph" -msgstr "Graphik Verlauf" +msgstr "Diagramm" #. module: base #: model:ir.model,name:base.model_ir_actions_server @@ -16687,12 +17636,12 @@ msgstr "Kanadische Buchführung" #: model:ir.ui.menu,name:base.menu_ir_actions_todo_form #: model:ir.ui.menu,name:base.next_id_11 msgid "Configuration Wizards" -msgstr "Installationsassistent" +msgstr "Installationsassistenten" #. module: base #: field:res.lang,code:0 msgid "Locale Code" -msgstr "LOCALE Code" +msgstr "Landesschlüssel (locale)" #. module: base #: field:workflow.activity,split_mode:0 @@ -16707,7 +17656,7 @@ msgstr "Beachten Sie, dass dieser Vorgang einige Zeit dauern kann." #. module: base #: model:ir.ui.menu,name:base.menu_localisation msgid "Localisation" -msgstr "Partner Herkunft" +msgstr "Landestypische Einstellungen" #. module: base #: field:ir.sequence,implementation:0 @@ -16734,22 +17683,23 @@ msgstr "Ausführung" #: view:ir.values:0 #: field:workflow.transition,condition:0 msgid "Condition" -msgstr "Bedingung" +msgstr "Zustand" #. module: base #: help:res.currency,rate:0 msgid "The rate of the currency to the currency of rate 1." msgstr "" +"Der Kurs der Währung verglichen mit der Vergleichswährung zum Kurs von 1" #. module: base #: field:ir.ui.view,name:0 msgid "View Name" -msgstr "Ansicht Bezeichnung" +msgstr "Ansichtsbezeichnung" #. module: base #: model:ir.module.module,shortdesc:base.module_document_ftp msgid "Shared Repositories (FTP)" -msgstr "Gemeinsames Verzeichnis (FTP)" +msgstr "Gemeinsame Verzeichnisse (FTP)" #. module: base #: model:ir.model,name:base.model_res_groups @@ -16783,7 +17733,7 @@ msgstr "Kroatien" #. module: base #: field:ir.actions.server,mobile:0 msgid "Mobile No" -msgstr "Mobile" +msgstr "Handy-Nr." #. module: base #: model:ir.actions.act_window,name:base.action_partner_by_category @@ -16792,7 +17742,7 @@ msgstr "Mobile" #: model:ir.ui.menu,name:base.menu_partner_category_form #: view:res.partner.category:0 msgid "Partner Categories" -msgstr "Partner Kategorien" +msgstr "Partnerkategorien" #. module: base #: view:base.module.upgrade:0 @@ -16802,12 +17752,12 @@ msgstr "Systemaktualisierung" #. module: base #: selection:ir.translation,type:0 msgid "Wizard Field" -msgstr "Assistent Datenfeld" +msgstr "Assistent.Datenfeld" #. module: base #: help:ir.sequence,prefix:0 msgid "Prefix value of the record for the sequence" -msgstr "Vorlauf (Prefix) einer Sequenz" +msgstr "Präfix einer Folgen" #. module: base #: model:res.country,name:base.sc @@ -16828,7 +17778,7 @@ msgstr "Bankkonten" #: field:ir.model,modules:0 #: field:ir.model.fields,modules:0 msgid "In modules" -msgstr "In Modul" +msgstr "In Modulen" #. module: base #: model:res.country,name:base.sl @@ -16839,7 +17789,7 @@ msgstr "Sierra Leone" #: view:res.company:0 #: view:res.partner:0 msgid "General Information" -msgstr "Grundinformation" +msgstr "Allgemeine Informationen" #. module: base #: model:res.country,name:base.tc @@ -16849,18 +17799,18 @@ msgstr "Turks- und Caicosinseln" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_project_issue msgid "eMail Gateway for Project Issues" -msgstr "" +msgstr "EMail-Schnittstelle zu Projektprobleme" #. module: base #: field:res.partner.bank,partner_id:0 msgid "Account Owner" -msgstr "Konto Inhaber" +msgstr "Konto-Inhaber" #. module: base #: code:addons/base/res/res_users.py:270 #, python-format msgid "Company Switch Warning" -msgstr "Unternehmenswechsel Warnhinweis" +msgstr "Warnhinweis zum Unternehmenswechsel" #. module: base #: model:res.country,name:base.ge @@ -16872,19 +17822,22 @@ msgstr "Georgien" msgid "" "Helps you manage your manufacturing processes and generate reports on those " "processes." -msgstr "Management Ihrer Fertigungsprozesse und Erstellung von Auswertungen" +msgstr "" +"Unterstützt Sie bei Ihren Produktionsprozessen und stellt die Berichte für " +"diese Prozesse zur Verfügung." #. module: base #: help:ir.sequence,number_increment:0 msgid "The next number of the sequence will be incremented by this number" -msgstr "Die nächste Nummer dieser Sequenz wir um diese Zahl erhöht." +msgstr "Die nächste Zahl dieser Folge wird um diesen Wert erhöht." #. module: base #: code:addons/orm.py:341 #, python-format msgid "Wrong ID for the browse record, got %r, expected an integer." msgstr "" -"Falsche ID für den Datensatz, erhalte %r, erwarte aber einen integer Wert" +"Falsche Kennung für den gesuchten Datensatz, erhielt %r, erwartet wurde ein " +"ganzzahliger Wert." #. module: base #: field:res.partner.address,function:0 @@ -16895,7 +17848,7 @@ msgstr "Funktion" #. module: base #: view:res.widget:0 msgid "Search Widget" -msgstr "Such Widget" +msgstr "Anzeigeelement für Suche" #. module: base #: model:ir.module.category,description:base.module_category_customer_relationship_management @@ -16903,6 +17856,12 @@ msgid "" "Manage relations with prospects and customers using leads, opportunities, " "requests or issues." msgstr "" +"Verwalten Sie Ihre Beziehungen zu Interessenten und Kunden. Nutzen Sie dabei " +"\r\n" +"Leads = Vorverhandlungen, \r\n" +"Opportunities = Gelegenheiten, \r\n" +"Requests = Anfragen oder \r\n" +"Issues = Problembearbeitungen." #. module: base #: selection:res.partner.address,type:0 @@ -16913,7 +17872,7 @@ msgstr "Lieferung" #: model:res.partner.title,name:base.res_partner_title_pvt_ltd #: model:res.partner.title,shortcut:base.res_partner_title_pvt_ltd msgid "Corp." -msgstr "GmbH" +msgstr "Gesellschaft" #. module: base #: model:ir.module.module,shortdesc:base.module_purchase_requisition @@ -16928,7 +17887,7 @@ msgstr "Monate" #. module: base #: view:workflow.instance:0 msgid "Workflow Instances" -msgstr "Workflow Objekte" +msgstr "Arbeitsablauf-Abschnitte" #. module: base #: code:addons/base/res/res_partner.py:284 @@ -16949,7 +17908,7 @@ msgstr "Nordkorea" #. module: base #: selection:ir.actions.server,state:0 msgid "Create Object" -msgstr "Erzeuge Objekt" +msgstr "Objekt anlegen" #. module: base #: view:ir.filters:0 @@ -16960,7 +17919,7 @@ msgstr "Kontext" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_mrp msgid "Sales and MRP Management" -msgstr "Verkauf und Prokuktions Management" +msgstr "Verkaufs- und Fertigungsplanung" #. module: base #: model:ir.actions.act_window,name:base.action_partner_sms_send @@ -16975,12 +17934,12 @@ msgstr "Interessent" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_invoice_directly msgid "Invoice Picking Directly" -msgstr "" +msgstr "Rechnung aus Lieferung" #. module: base #: selection:base.language.install,lang:0 msgid "Polish / Język polski" -msgstr "Polish / Język polski" +msgstr "Polnisch / Język polski" #. module: base #: model:ir.module.module,description:base.module_base_tools @@ -16993,11 +17952,19 @@ msgid "" "are accessible if installed.\n" " " msgstr "" +"\n" +"Gemeinsame Grundlagen für Hilfs-Module.\n" +"===================================\n" +"\n" +"Legt ein Menü an, in dem Hilfsmittel wie Umfrage, Mittagspause, Ideen, ... " +"verfügbar gemacht \n" +"werden, sobald diese installiert werden.\n" +" " #. module: base #: field:ir.exports,name:0 msgid "Export Name" -msgstr "Export Name" +msgstr "Exportbezeichnung" #. module: base #: help:res.partner.address,type:0 @@ -17005,14 +17972,14 @@ msgid "" "Used to select automatically the right address according to the context in " "sales and purchases documents." msgstr "" -"Wird angewendet um automatisch die eingestellten Zuordnungen wählen zu " -"können." +"Wird angewendet um automatisch die eingestellten Zuordnungen zu\r\n" +"Verkäufen und Einkäufen wählen zu können." #. module: base #: model:ir.actions.act_window,name:base.res_widget_act_window #: model:ir.ui.menu,name:base.menu_res_widget_act_window msgid "Homepage Widgets" -msgstr "Homepage Widgets" +msgstr "Startseiten Anzeige-Elemente" #. module: base #: help:res.company,rml_footer2:0 @@ -17020,6 +17987,9 @@ msgid "" "This field is computed automatically based on bank accounts defined, having " "the display on footer checkbox set." msgstr "" +"Dieses Feld wird, basierend auf Ihren Kontoangaben, automatisch " +"zusammengestellt, wenn Sie\r\n" +"'Anzeige in Fusszeile' eingeschaltet haben." #. module: base #: model:ir.module.module,description:base.module_mrp_subproduct @@ -17039,6 +18009,20 @@ msgid "" " A + B + C -> D + E\n" " " msgstr "" +"\n" +"Dieses Modul setzt die Herstellung mehrerer Produkte aus einem " +"Fertigungsauftrag um.\n" +"=========================================================================\n" +"\n" +"Sie können Teilprodukte in der Stückliste festlegen.\n" +"\n" +"Ohne das Modul ist:\n" +" A + B + C -> D\n" +"\n" +"Mit diesem Modul ist auch:\n" +" A + B + C -> D + E\n" +"im System darstellbar.\n" +" " #. module: base #: model:res.country,name:base.lk @@ -17071,11 +18055,43 @@ msgid "" "module.\n" " " msgstr "" +"\n" +"Dieses Modul ermöglicht Ihnen die Anlage eines neuen Moduls ohne jede " +"Entwicklung.\n" +"========================================================================\n" +"\n" +"Es zeichnet alle Tätigkeiten/Vorgänge an Objekten während einer " +"Aufnahmesitzung auf\n" +"und speichert diese als .ZIP-Archiv ab. Auf diese Weise erstellen Sie Ihr " +"eigenes Modul \n" +"unmittelbar vom OpenERP-Klienten aus.\n" +"\n" +"Diese Version erlaubt dabei die Erstellung und Aktualisierung bestehender " +"Datensätze.\n" +"Es werden Abhängikeiten und Verknüpfung zwischen allerlei Dargestellter " +"Elemente \n" +"(m:1, m:n, ...) ermittelt. Ebenso werden Arbeitsabläufe und Beispiel-" +"/Testdaten \n" +"unterstützt.\n" +"\n" +"Dies sollte es Ihnen leichter machen wiederverwendbare und veröffentlichbare " +"Module\n" +"für individuelle Konfigurationen wie auch Testumgebungen zu erstellen.\n" +"\n" +"Wie wird es verwendet?\n" +"Rufe \n" +"Administration/Einstellungen/Modulerstellung/Assistent Anpassungen als Modul " +"exportieren\n" +"auf.\n" +"Gebe Sie Zeit/Datum der Aufzeichnung und der betroffenen Objekte an und " +"beginnen\n" +"dann die Aufzeichnung.\n" +" " #. module: base #: selection:base.language.install,lang:0 msgid "Russian / русский язык" -msgstr "Russian / русский язык" +msgstr "Russisch / русский язык" #~ msgid "Metadata" #~ msgstr "Metadaten" diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po index 32caf4f4d84..494dd7644b9 100644 --- a/openerp/addons/base/i18n/el.po +++ b/openerp/addons/base/i18n/el.po @@ -12,8 +12,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" "X-Poedit-Country: GREECE\n" "X-Poedit-Language: Greek\n" "X-Poedit-SourceCharset: utf-8\n" diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po index 1d2ab6fd748..dd91a5c2cd6 100644 --- a/openerp/addons/base/i18n/en_GB.po +++ b/openerp/addons/base/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index c556dbc1078..1f9565339c8 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po index b7aad7682c3..81edd41b083 100644 --- a/openerp/addons/base/i18n/es_AR.po +++ b/openerp/addons/base/i18n/es_AR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh @@ -25,17 +25,17 @@ msgstr "Santa Helena" #. module: base #: view:ir.actions.report.xml:0 msgid "Other Configuration" -msgstr "" +msgstr "Otra configuración" #. module: base #: selection:ir.property,type:0 msgid "DateTime" -msgstr "" +msgstr "Fecha y hora" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "" +msgstr "Integración Tareas-Email" #. module: base #: code:addons/fields.py:582 @@ -44,6 +44,8 @@ msgid "" "The second argument of the many2many field %s must be a SQL table !You used " "%s, which is not a valid SQL table name." msgstr "" +"¡El segundo argumento del campo many2many %s debe ser una tabla SQL! Has " +"utilizado %s, que no es un nombre de tabla SQL válido." #. module: base #: field:ir.ui.view,arch:0 @@ -70,6 +72,21 @@ msgid "" " * Graph of My Remaining Hours by Project\n" " " msgstr "" +"\n" +"El módulo de Gestión de Proyectos permite gestionar proyectos con varios " +"niveles, tareas, trabajo realizado en tareas, etc.\n" +"=============================================================================" +"=========\n" +"\n" +"Es capaz de generar planificaciones, ordenar tareas, etc.\n" +"\n" +"El tablero de control para los miembros del proyecto incluye:\n" +"--------------------------------------------\n" +"* Lista de mis tareas abiertas\n" +"* Lista de mis tareas delegadas\n" +"* Gráfico de mis proyectos: Planificado vs Horas totales\n" +"* Gráfico de mis horas pendientes por proyecto\n" +" " #. module: base #: field:base.language.import,code:0 @@ -89,7 +106,7 @@ msgstr "Workflow" #. module: base #: selection:ir.sequence,implementation:0 msgid "No gap" -msgstr "" +msgstr "Sin hueco" #. module: base #: selection:base.language.install,lang:0 @@ -99,7 +116,7 @@ msgstr "Húngaro / Magyar" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PY) / Español (PY)" -msgstr "" +msgstr "Español (UY) / Español (UY)" #. module: base #: model:ir.module.category,description:base.module_category_project_management @@ -107,22 +124,26 @@ msgid "" "Helps you manage your projects and tasks by tracking them, generating " "plannings, etc..." msgstr "" +"Le ayuda a gestionar sus proyectos y tareas realizando un seguimiento de los " +"mismos, generando planificaciones, ..." #. module: base #: field:ir.actions.act_window,display_menu_tip:0 msgid "Display Menu Tips" -msgstr "" +msgstr "Mostrar consejos de menú" #. module: base #: help:ir.cron,model:0 msgid "" "Model name on which the method to be called is located, e.g. 'res.partner'." msgstr "" +"Nombre del módelo en el que se encuentra el método al que se llama, por " +"ejemplo 'res.partner'." #. module: base #: view:ir.module.module:0 msgid "Created Views" -msgstr "" +msgstr "Vistas creadas" #. module: base #: code:addons/base/ir/ir_model.py:532 @@ -131,6 +152,8 @@ msgid "" "You can not write in this document (%s) ! Be sure your user belongs to one " "of these groups: %s." msgstr "" +"¡No puede escribir en este documento (%s)! Asegúrese que su usuario " +"pertenezca a alguno de estos grupos: %s." #. module: base #: model:ir.module.module,description:base.module_event_project @@ -141,6 +164,11 @@ msgid "" "\n" "This module allows you to create retro planning for managing your events.\n" msgstr "" +"\n" +"Organización y gestión de eventos.\n" +"======================================\n" +"\n" +"Este módulo permite crear retro planning para gestionar tus eventos.\n" #. module: base #: help:ir.model.fields,domain:0 @@ -149,16 +177,19 @@ msgid "" "specified as a Python expression defining a list of triplets. For example: " "[('color','=','red')]" msgstr "" +"El dominio opcional para restringir los posibles valores para los campos de " +"relación, se especifica como una expresión Python compuesta por una lista de " +"tripletas. Por ejemplo: [('color','=',' red')]" #. module: base #: field:res.partner,ref:0 msgid "Reference" -msgstr "" +msgstr "Referencia" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_be_invoice_bba msgid "Belgium - Structured Communication" -msgstr "" +msgstr "Bélgica - Comunicación Estructurada" #. module: base #: field:ir.actions.act_window,target:0 @@ -168,12 +199,12 @@ msgstr "Ventana destino" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_analytic_plans msgid "Sales Analytic Distribution" -msgstr "" +msgstr "Distribución Analítica de Ventas" #. module: base #: model:ir.module.module,shortdesc:base.module_web_process msgid "Process" -msgstr "" +msgstr "Procesar" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_journal_billing_rate diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po index 50a7f8e0821..aedc3181be1 100644 --- a/openerp/addons/base/i18n/es_CL.po +++ b/openerp/addons/base/i18n/es_CL.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_CR.po b/openerp/addons/base/i18n/es_CR.po index c2e8afd5c28..636ed963d30 100644 --- a/openerp/addons/base/i18n/es_CR.po +++ b/openerp/addons/base/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" "Language: \n" #. module: base diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po index 60f34c370f2..84617d0a2bc 100644 --- a/openerp/addons/base/i18n/es_EC.po +++ b/openerp/addons/base/i18n/es_EC.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_MX.po b/openerp/addons/base/i18n/es_MX.po index 57fa84aff0b..3e7f975f118 100644 --- a/openerp/addons/base/i18n/es_MX.po +++ b/openerp/addons/base/i18n/es_MX.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po index 57ffc20ad23..9d8b95b83c9 100644 --- a/openerp/addons/base/i18n/et.po +++ b/openerp/addons/base/i18n/et.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po index 277c9ff2d1d..cf88512fe08 100644 --- a/openerp/addons/base/i18n/eu.po +++ b/openerp/addons/base/i18n/eu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po index 5eaefa28efb..98f1b514c4b 100644 --- a/openerp/addons/base/i18n/fa.po +++ b/openerp/addons/base/i18n/fa.po @@ -9,8 +9,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" "X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" "X-Poedit-Language: Persian\n" @@ -22,7 +22,7 @@ msgstr "سنت هلن" #. module: base #: view:ir.actions.report.xml:0 msgid "Other Configuration" -msgstr "" +msgstr "پیکربندی های دیگر" #. module: base #: selection:ir.property,type:0 @@ -81,12 +81,12 @@ msgstr "کد (مثلا:en__US)" #: field:workflow.transition,wkf_id:0 #: field:workflow.workitem,wkf_id:0 msgid "Workflow" -msgstr "کارگردش" +msgstr "گردش کار" #. module: base #: selection:ir.sequence,implementation:0 msgid "No gap" -msgstr "" +msgstr "بدون فاصله" #. module: base #: selection:base.language.install,lang:0 @@ -96,7 +96,7 @@ msgstr "مجاری / Magyar" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PY) / Español (PY)" -msgstr "" +msgstr "اسپانیایی" #. module: base #: model:ir.module.category,description:base.module_category_project_management @@ -108,7 +108,7 @@ msgstr "" #. module: base #: field:ir.actions.act_window,display_menu_tip:0 msgid "Display Menu Tips" -msgstr "" +msgstr "نمایش منوی نکات" #. module: base #: help:ir.cron,model:0 @@ -150,12 +150,12 @@ msgstr "" #. module: base #: field:res.partner,ref:0 msgid "Reference" -msgstr "" +msgstr "ارجاع" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_be_invoice_bba msgid "Belgium - Structured Communication" -msgstr "" +msgstr "بلژیک ساختار ارتباطات" #. module: base #: field:ir.actions.act_window,target:0 @@ -170,7 +170,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_web_process msgid "Process" -msgstr "" +msgstr "روند" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_journal_billing_rate @@ -181,7 +181,7 @@ msgstr "" #: code:addons/base/res/res_users.py:558 #, python-format msgid "Warning!" -msgstr "" +msgstr "هشدار!" #. module: base #: code:addons/base/ir/ir_model.py:344 @@ -217,12 +217,12 @@ msgstr "سوازیلند" #: code:addons/orm.py:4206 #, python-format msgid "created." -msgstr "" +msgstr "ایجاد میشود." #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_tr msgid "Turkey - Accounting" -msgstr "" +msgstr "ترکیه - حسابداری" #. module: base #: model:ir.module.module,shortdesc:base.module_mrp_subproduct @@ -260,7 +260,7 @@ msgstr "" #: model:ir.module.category,name:base.module_category_sales_management #: model:ir.module.module,shortdesc:base.module_sale msgid "Sales Management" -msgstr "" +msgstr "مدیریت فروش" #. module: base #: view:res.partner:0 @@ -271,7 +271,7 @@ msgstr "جستجوی همکار" #: code:addons/base/module/wizard/base_export_language.py:60 #, python-format msgid "new" -msgstr "تازه" +msgstr "جدید" #. module: base #: field:ir.actions.report.xml,multi:0 @@ -304,7 +304,7 @@ msgstr "اندازه بیشینه" #: model:ir.ui.menu,name:base.next_id_73 #: model:ir.ui.menu,name:base.reporting_menu msgid "Reporting" -msgstr "" +msgstr "گزارش" #. module: base #: view:res.partner:0 @@ -337,7 +337,7 @@ msgstr "" #. module: base #: sql_constraint:res.lang:0 msgid "The name of the language must be unique !" -msgstr "" +msgstr "نام زبان باید منحصر به فرد باشد !" #. module: base #: model:ir.module.module,description:base.module_import_base @@ -356,7 +356,7 @@ msgstr "نام تردست" #. module: base #: model:res.groups,name:base.group_partner_manager msgid "Partner Manager" -msgstr "" +msgstr "مدیریت شریک" #. module: base #: model:ir.module.category,name:base.module_category_customer_relationship_management @@ -366,7 +366,7 @@ msgstr "" #. module: base #: view:ir.module.module:0 msgid "Extra" -msgstr "" +msgstr "اضافی" #. module: base #: code:addons/orm.py:2526 @@ -387,7 +387,7 @@ msgstr "حد اعتبار" #. module: base #: model:ir.module.module,description:base.module_web_graph msgid "Openerp web graph view" -msgstr "" +msgstr "مشاهده گراف Openerp در وب" #. module: base #: field:ir.model.data,date_update:0 @@ -402,7 +402,7 @@ msgstr "" #. module: base #: view:ir.attachment:0 msgid "Owner" -msgstr "" +msgstr "مالک‌" #. module: base #: field:ir.actions.act_window,src_model:0 @@ -428,7 +428,7 @@ msgstr "ir.ui.view_sc" #: field:res.widget.user,widget_id:0 #: field:res.widget.wizard,widgets_list:0 msgid "Widget" -msgstr "" +msgstr "ویجت" #. module: base #: view:ir.model.access:0 @@ -454,7 +454,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_pad_project msgid "Specifications on PADs" -msgstr "" +msgstr "مشخصات به روی پد" #. module: base #: help:ir.filters,user_id:0 @@ -466,7 +466,7 @@ msgstr "" #. module: base #: help:res.partner,website:0 msgid "Website of Partner." -msgstr "" +msgstr "وب سایت همکار" #. module: base #: help:ir.actions.act_window,views:0 @@ -495,13 +495,13 @@ msgstr "قالب تاریخ" #. module: base #: model:ir.module.module,shortdesc:base.module_base_report_designer msgid "OpenOffice Report Designer" -msgstr "" +msgstr "طراح گزارش اپن آفیس" #. module: base #: field:res.bank,email:0 #: field:res.partner.address,email:0 msgid "E-Mail" -msgstr "ایمیل" +msgstr "پست الکترونیکی" #. module: base #: model:res.country,name:base.an @@ -532,7 +532,7 @@ msgstr "" #. module: base #: model:res.country,name:base.gf msgid "French Guyana" -msgstr "امریکا/گویانا" +msgstr "گوویان فرانسوی" #. module: base #: field:ir.ui.view.custom,ref_id:0 @@ -556,22 +556,22 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_layout msgid "Sales Orders Print Layout" -msgstr "" +msgstr "چیدمان سفارش های فروش در چاپ" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (VE) / Español (VE)" -msgstr "" +msgstr "اسپانیایی (VE)" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_timesheet_invoice msgid "Invoice on Timesheets" -msgstr "" +msgstr "فاکتور در جداول زمانبندی" #. module: base #: view:base.module.upgrade:0 msgid "Your system will be updated." -msgstr "" +msgstr "سیستم شما به روز خواهد شد." #. module: base #: field:ir.actions.todo,note:0 @@ -641,7 +641,7 @@ msgstr "فروش‌ها و خریدها" #. module: base #: view:ir.translation:0 msgid "Untranslated" -msgstr "" +msgstr "ترجمه‌نشده" #. module: base #: help:ir.actions.act_window,context:0 @@ -670,7 +670,7 @@ msgstr "نام فیلدهای دلخواه باید با 'x_' آغاز شوند! #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_mx msgid "Mexico - Accounting" -msgstr "" +msgstr "حسابداری - مکزیک" #. module: base #: help:ir.actions.server,action_id:0 @@ -680,17 +680,17 @@ msgstr "پنچره کُنش، گزارش، تَردست را برای اجرا #. module: base #: model:res.country,name:base.ai msgid "Anguilla" -msgstr "آنگیل" +msgstr "آنگولا" #. module: base #: view:base.language.export:0 msgid "Export done" -msgstr "برونش انجام شد" +msgstr "صادرات انجام شد" #. module: base #: model:ir.module.module,shortdesc:base.module_plugin_outlook msgid "Outlook Plug-In" -msgstr "" +msgstr "پلاگین Outlook" #. module: base #: view:ir.model:0 @@ -717,7 +717,7 @@ msgstr "اردن" #. module: base #: help:ir.cron,nextcall:0 msgid "Next planned execution date for this job." -msgstr "" +msgstr "تاریخ برنامه ریزی شده بعدی برای انجام این کار" #. module: base #: code:addons/base/ir/ir_model.py:139 @@ -733,24 +733,24 @@ msgstr "اریتره" #. module: base #: sql_constraint:res.company:0 msgid "The company name must be unique !" -msgstr "" +msgstr "نام شرکت باید منحصر به فرد باشد !" #. module: base #: view:res.config:0 #: view:res.config.installer:0 msgid "description" -msgstr "" +msgstr "توضیحات" #. module: base #: model:ir.ui.menu,name:base.menu_base_action_rule #: model:ir.ui.menu,name:base.menu_base_action_rule_admin msgid "Automated Actions" -msgstr "" +msgstr "عملیات خودکار" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_ro msgid "Romania - Accounting" -msgstr "" +msgstr "حسابداری - رومانی" #. module: base #: view:partner.wizard.ean.check:0 diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po index 705225800be..4455b4b1bc2 100644 --- a/openerp/addons/base/i18n/fa_AF.po +++ b/openerp/addons/base/i18n/fa_AF.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po index 8872be9f858..a636d8a94c2 100644 --- a/openerp/addons/base/i18n/fi.po +++ b/openerp/addons/base/i18n/fi.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po index a34898b563d..5401ac31f42 100644 --- a/openerp/addons/base/i18n/fr.po +++ b/openerp/addons/base/i18n/fr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po index 42b2e066b40..4d020749af9 100644 --- a/openerp/addons/base/i18n/gl.po +++ b/openerp/addons/base/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/gu.po b/openerp/addons/base/i18n/gu.po index 11b6b06b141..da4a5d6d519 100644 --- a/openerp/addons/base/i18n/gu.po +++ b/openerp/addons/base/i18n/gu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po index 03864ff34aa..dc41897f839 100644 --- a/openerp/addons/base/i18n/he.po +++ b/openerp/addons/base/i18n/he.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po index 78d5591663d..9006415c054 100644 --- a/openerp/addons/base/i18n/hr.po +++ b/openerp/addons/base/i18n/hr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:40+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" "Language: hr\n" #. module: base diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po index 85823b7f6f2..d421d8874de 100644 --- a/openerp/addons/base/i18n/hu.po +++ b/openerp/addons/base/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po index 14dce614f0b..038dd4c0a68 100644 --- a/openerp/addons/base/i18n/hy.po +++ b/openerp/addons/base/i18n/hy.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po index c72c52beeb4..57806edb71c 100644 --- a/openerp/addons/base/i18n/id.po +++ b/openerp/addons/base/i18n/id.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po index e136665ae18..e5fa01a9dbd 100644 --- a/openerp/addons/base/i18n/is.po +++ b/openerp/addons/base/i18n/is.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po index e2e252f260c..cf39f48fe37 100644 --- a/openerp/addons/base/i18n/it.po +++ b/openerp/addons/base/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po index 4ef99b6c764..8a6a41057ec 100644 --- a/openerp/addons/base/i18n/ja.po +++ b/openerp/addons/base/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ka.po b/openerp/addons/base/i18n/ka.po index d8eddbdd1c9..00a06bf9ba3 100644 --- a/openerp/addons/base/i18n/ka.po +++ b/openerp/addons/base/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:37+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:12+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po index 30d6d020389..b17421be2f6 100644 --- a/openerp/addons/base/i18n/kk.po +++ b/openerp/addons/base/i18n/kk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:38+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po index bb02ef1a9c1..7a568c31b84 100644 --- a/openerp/addons/base/i18n/ko.po +++ b/openerp/addons/base/i18n/ko.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:13+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po index 1c0589ae931..e08c3f152b9 100644 --- a/openerp/addons/base/i18n/lt.po +++ b/openerp/addons/base/i18n/lt.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po index e02fdd7e749..27705b72e48 100644 --- a/openerp/addons/base/i18n/lv.po +++ b/openerp/addons/base/i18n/lv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po index e7b89f876f9..2d66015cdb7 100644 --- a/openerp/addons/base/i18n/mk.po +++ b/openerp/addons/base/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po index 4dbca25f61f..1264b368a92 100644 --- a/openerp/addons/base/i18n/mn.po +++ b/openerp/addons/base/i18n/mn.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po index 677dbb18e89..2a83f20f87f 100644 --- a/openerp/addons/base/i18n/nb.po +++ b/openerp/addons/base/i18n/nb.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po index f4b58866f1a..4ec2d171e4d 100644 --- a/openerp/addons/base/i18n/nl.po +++ b/openerp/addons/base/i18n/nl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:36+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:11+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh @@ -397,7 +397,7 @@ msgstr "Naam assistent" #. module: base #: model:res.groups,name:base.group_partner_manager msgid "Partner Manager" -msgstr "Relatie manager" +msgstr "Relatiemanager" #. module: base #: model:ir.module.category,name:base.module_category_customer_relationship_management @@ -1403,7 +1403,7 @@ msgstr "Document Beheer Systeem" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_claim msgid "Claims Management" -msgstr "Claimsmanagement" +msgstr "Klachtenregistratie" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root @@ -1453,7 +1453,7 @@ msgid "" " * Effective Date\n" msgstr "" "\n" -"deze module voegt extra informatie toe aan een verkooporder.\n" +"Deze module voegt extra informatie toe aan een verkooporder.\n" "===================================================\n" "\n" "U kunt de navolgende extra data toevoegen aan een verkooporder:\n" @@ -2502,8 +2502,8 @@ msgstr "" "Helpdesk management.\n" "===================\n" "\n" -"Net als administratie en verwerking van claims is de Helpdesk en " -"ondersteuning tool, een goed instrument\n" +"Net als de klachtenregistratie module is de Helpdesk en ondersteuning tool, " +"een goed instrument\n" "om uw acties vast te leggen. Dit menu is meer aangepast aan de mondelinge " "communicatie,\n" "die niet noodzakelijkerwijs verband houden met een claim. Selecteer een " @@ -2614,7 +2614,7 @@ msgstr "Ideeën" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_crm msgid "Opportunity to Quotation" -msgstr "Verkoopkans naar offerte" +msgstr "Prospect naar offerte" #. module: base #: model:ir.module.module,description:base.module_sale_analytic_plans @@ -4255,6 +4255,15 @@ msgid "" "automatically new claims based on incoming emails.\n" " " msgstr "" +"\n" +"Met deze module kunt u alle klachten van uw klanten en leveranciers " +"registreren.\n" +"==================================================================\n" +"\n" +"Deze module is volledig geïntegreerd met de e-mail gateway, zodat u " +"automatisch\n" +"nieuwe klachten kunt registreren op basis van inkomende e-mails.\n" +" " #. module: base #: selection:workflow.activity,join_mode:0 @@ -7672,7 +7681,7 @@ msgstr "Canada" #: code:addons/base/res/res_company.py:158 #, python-format msgid "Reg: " -msgstr "Reg: " +msgstr "KVK: " #. module: base #: help:res.currency.rate,currency_rate_type_id:0 @@ -12076,7 +12085,7 @@ msgstr "Wizards welke worden gestart" #: model:ir.module.category,name:base.module_category_manufacturing #: model:ir.ui.menu,name:base.menu_mrp_root msgid "Manufacturing" -msgstr "Productie" +msgstr "Productiebeheer" #. module: base #: model:res.country,name:base.km @@ -14542,7 +14551,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_crm_claim msgid "eMail Gateway for CRM Claim" -msgstr "E-mail Gateway voor CRM Claims" +msgstr "E-mail Gateway voor klachtenregistratie" #. module: base #: help:res.partner,supplier:0 diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po index 0a395831749..1313f114d81 100644 --- a/openerp/addons/base/i18n/nl_BE.po +++ b/openerp/addons/base/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po index 52e1c9360e5..4ad08ff73d8 100644 --- a/openerp/addons/base/i18n/pl.po +++ b/openerp/addons/base/i18n/pl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:39+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:14+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po index 14363c33a2d..11e1ff3a38e 100644 --- a/openerp/addons/base/i18n/pt.po +++ b/openerp/addons/base/i18n/pt.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:40+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po index 342d9754602..eb3b7918c24 100644 --- a/openerp/addons/base/i18n/pt_BR.po +++ b/openerp/addons/base/i18n/pt_BR.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh @@ -1944,6 +1944,47 @@ msgid "" "\n" " " msgstr "" +"\n" +"Validação de IVA para os números Parceiros 'IVA\n" +"========================================\n" +"\n" +"Depois de instalar este módulo, os valores inseridos no domínio do IVA de " +"parceiros\n" +"ser validado para todos os países suportados. O país é inferida a partir da\n" +"2-letra código do país que prefixos o número de IVA, por exemplo, `` `` " +"BE0477472701\n" +"será validado usando as regras belgas.\n" +"\n" +"Existem dois níveis diferentes de validação Número de IVA:\n" +"\n" +"  * Por padrão, uma verificação off-line simples é realizado utilizando a " +"validação conhecido\n" +"    regras para o país, geralmente uma verificação simples dígito. Isto é " +"rápido e\n" +"    sempre disponível, mas permite que os números que não são " +"verdadeiramente talvez alocados,\n" +"    ou não mais válido.\n" +"  * Quando os \"VIES IVA Verifique\" está activada (na configuração do " +"usuário do\n" +"    Empresa), números de IVA será submetido ao invés linha UE VIES\n" +"    banco de dados, o que vai realmente verificar se o número é válido e, " +"atualmente,\n" +"    atribuídos a uma empresa da UE. Este é um pouco mais lento do que o " +"simples\n" +"    off-line, cheque, requer uma ligação à Internet, e pode não estar " +"disponível\n" +"    o tempo todo. Se o serviço não está disponível ou não suporta o\n" +"    país requerido (por exemplo, para países fora da UE), uma simples " +"verificação será realizada\n" +"    em vez disso.\n" +"\n" +"Países suportados atualmente são os países da UE, e alguns países não " +"comunitários\n" +"como Chile, Colômbia, México, Noruega ou a Rússia. Para os países não " +"suportados,\n" +"apenas o código do país serão validados.\n" +"\n" +" " #. module: base #: view:ir.sequence:0 @@ -2467,6 +2508,22 @@ msgid "" "re-invoice your customer's expenses if your work by project.\n" " " msgstr "" +"\n" +"Este módulo tem como objetivo gerenciar as despesas dos funcionários.\n" +"===============================================\n" +"\n" +"O fluxo de trabalho inteiro é implementado:\n" +"     * Projeto de despesa\n" +"     * Confirmação da folha pelo empregado\n" +"     * Validação por seu empresário\n" +"     * A validação pelo contador e criação de fatura\n" +"     * Pagamento da fatura para o empregado\n" +"\n" +"Este módulo também utiliza a contabilidade analítica e é compatível com a\n" +"a fatura no módulo de folha de ponto, de modo que você vai ser capaz de " +"automaticamente\n" +"cobrar seu cliente despesas se você trabalhar por projeto.\n" +" " #. module: base #: field:ir.values,action_id:0 @@ -2948,6 +3005,31 @@ msgid "" "performing those tasks.\n" " " msgstr "" +"\n" +"Este módulo implementa todos os conceitos definidos pela metodologia GTD - " +"Getting Things Done.\n" +"================================================== " +"=================================\n" +"\n" +"Este módulo implementa um simples lista Todo pessoal baseado em tarefas. Ele " +"acrescenta\n" +"a aplicação do projeto uma lista editável de tarefas simplificadas para o " +"mínimo\n" +"campos obrigatórios.\n" +"\n" +"A lista de afazeres é baseado na metodologia GTD. Esta metodologia " +"mundialmente utilizada\n" +"é utilizado para a melhoria pessoal de gerenciamento de tempo.\n" +"\n" +"Getting Things Done (comumente abreviado como GTD) é uma ação de gestão\n" +"método criado por David Allen, e descrito em um livro de mesmo nome.\n" +"\n" +"GTD se baseia no princípio de que uma pessoa precisa para mover as tarefas " +"fora da mente por\n" +"gravá-las externamente. Dessa forma, a mente se liberta do trabalho de\n" +"lembrando de tudo que precisa ser feito, e pode se concentrar em realmente\n" +"executar essas tarefas.\n" +" " #. module: base #: model:res.country,name:base.tt @@ -3084,7 +3166,7 @@ msgstr "Erro!" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_fr_rib msgid "French RIB Bank Details" -msgstr "" +msgstr "Detalhes do RIB do Banco Francês" #. module: base #: view:res.lang:0 @@ -3200,12 +3282,12 @@ msgid "" "The decimal precision is configured per company.\n" msgstr "" "\n" -"Você precisa configurar a precisão do preço para diferentes tipos de uso: " -"contabilidade, venda, compras, etc.\n" +"Configurar a precisão preço que você precisa para diferentes tipos de uso: " +"contabilidade, vendas, compras, etc\n" "=============================================================================" "=========================\n" "\n" -"A precisão decimal é configurada por empresa.\n" +"A precisão decimal é configurado por empresa.\n" #. module: base #: model:ir.module.module,description:base.module_l10n_pl @@ -3223,6 +3305,18 @@ msgid "" "że wszystkie towary są w obrocie hurtowym.\n" " " msgstr "" +"\n" +"Este é o módulo para gerenciar o gráfico contabilidade e impostos para a " +"Polónia no OpenERP.\n" +"================================================== " +"================================\n" +"\n" +"To jest moduł do tworzenia wzorcowego planu kont i podstawowych ustawień do " +"podatków\n" +"VAT 0%, 7% i 22%. Moduł ustawia też konta do kupna i sprzedaży towarów " +"zakładając,\n" +"że wszystkie towary są w obrocie hurtowym.\n" +" " #. module: base #: field:ir.actions.client,params_store:0 @@ -3258,6 +3352,21 @@ msgid "" "since it's the same which has been renamed.\n" " " msgstr "" +"\n" +"Este módulo permite aos usuários executar a segmentação entre os parceiros.\n" +"================================================== ===============\n" +"\n" +"Ele utiliza os critérios de perfis a partir do módulo de segmentação mais " +"cedo e melhorá-lo. Graças ao novo conceito de questionário. Agora você pode " +"reagrupar as perguntas em um questionário e usá-lo diretamente em um " +"parceiro.\n" +"\n" +"Ele também foi fundida com a anterior ferramenta de CRM & SRM segmentação " +"porque foram sobrepostos.\n" +"\n" +"     * Nota: Este módulo não é compatível com o módulo de segmentação, já " +"que é o mesmo que foi renomeado.\n" +" " #. module: base #: code:addons/report_sxw.py:434 @@ -3379,6 +3488,30 @@ msgid "" "\n" " " msgstr "" +"\n" +" \n" +"Localização belga para as facturas em-e de saída (pré-requisito para " +"account_coda):\n" +"     Rótulos 'referência' Renomear campo para 'Comunicação' -\n" +"     - Adicionar suporte para comunicação estruturada belga\n" +"\n" +"Uma comunicação estruturada pode ser gerado automaticamente em faturas de " +"saída de acordo com os seguintes algoritmos:\n" +"     1) aleatória: + + + RRR / RRRR / RRRDD + + +\n" +"         R. R =. Dígitos aleatórios, Dígitos DD = Verificar\n" +"     2) Data: + + + DOY / ano / SSSDD + + +\n" +"         Doy = dia do ano, o SSS = número de seqüência, DD dígitos = " +"Verificar)\n" +"     3) Referência ao Cliente + + + RRR / RRRR / SSSDDD + + +\n" +"         R.. = R Referência do cliente sem caracteres não numéricos, SSS = " +"Número sequencial, DD dígitos = Verificar)\n" +"        \n" +"O tipo preferido de comunicação estruturada e algoritmo associado pode ser " +"especificado nos registros de parceiros.\n" +"Uma comunicação \"aleatória\" estruturado gerado se nenhum algoritmo é " +"especificado no registro de parceiros. \n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_quality_manual @@ -3515,6 +3648,14 @@ msgid "" "for Wiki FAQ.\n" " " msgstr "" +"\n" +"Este módulo oferece um Wiki Modelo FAQ.\n" +"=========================================\n" +"\n" +"Ele fornece dados de demonstração, criando um Grupo de wiki e uma página " +"Wiki\n" +"para Wiki FAQ.\n" +" " #. module: base #: view:ir.actions.server:0 @@ -3789,6 +3930,13 @@ msgid "" " * the Tax Code Chart for Luxembourg\n" " * the main taxes used in Luxembourg" msgstr "" +"\n" +"Este é o módulo de base para gerenciar o Plano Contábil de Luxemburgo.\n" +"================================================== ====================\n" +"\n" +"     * Quadro da KLUWER de Contas,\n" +"     * O Gráfico Código Tributário para o Luxemburgo\n" +"     * Os principais impostos usados ​​no Luxemburgo" #. module: base #: field:ir.module.module,demo:0 @@ -3813,6 +3961,21 @@ msgid "" "module 'share'.\n" " " msgstr "" +"\n" +"Este módulo define \"portais\" para personalizar o acesso ao seu banco de " +"dados OpenERP\n" +"para usuários externos.\n" +"\n" +"Um portal define menu de usuário personalizada e direitos de acesso para um " +"grupo de usuários\n" +"(os associados a esse portal). Ela também se associa grupos de usuários para " +"o\n" +"usuários do portal (adicionando um grupo no portal adiciona automaticamente " +"para o portal\n" +"usuários, etc.) Essa característica é muito útil quando utilizada em " +"combinação com a\n" +"'share' módulo.\n" +" " #. module: base #: selection:res.request,priority:0 @@ -3959,6 +4122,22 @@ msgid "" "\n" " " msgstr "" +"\n" +"Este módulo oferece alguns recursos para melhorar o layout das faturas.\n" +"================================================== =======================\n" +"\n" +"Ele lhe dá a possibilidade de:\n" +"--------------------------------\n" +"     * Ordem todas as linhas de uma fatura\n" +"     * Adicionar títulos, linhas de comentário, sub total de linhas\n" +"     * Desenhar linhas horizontais e colocar quebras de página\n" +"\n" +"Além disso, há uma opção que permite a impressão de todas as faturas " +"selecionados com uma mensagem dada especial na parte inferior do mesmo. Este " +"recurso pode ser muito útil para imprimir as suas facturas com o fim-de-ano " +"desejos, condições especiais pontuais.\n" +"\n" +" " #. module: base #: constraint:res.partner:0 @@ -4156,6 +4335,14 @@ msgid "" "templates to target objects.\n" " " msgstr "" +"\n" +" * Apoio a Multi Idiomas de Plano de Contas, Impostos, códigos fiscais, " +"diários, Modelos de Contabilidade,\n" +"         Plano de Contas Analítico e Diários analíticos.\n" +"     * Assistente de Configuração mudanças\n" +"         - Copia traduções para COA, Imposto de Código Tributário, e Posição " +"Fiscal a partir de modelos para objetos de destino.\n" +" " #. module: base #: view:ir.actions.todo:0 @@ -4547,6 +4734,15 @@ msgid "" "automatically new claims based on incoming emails.\n" " " msgstr "" +"\n" +"Este módulo permite que você acompanhe as solicitações de seus clientes / " +"fornecedores.\n" +"================================================== " +"==============================\n" +"\n" +"É totalmente integrado com o gateway de e-mail para que você possa criar\n" +"automaticamente novos pedidos baseados em e-mails recebidos.\n" +" " #. module: base #: selection:workflow.activity,join_mode:0 @@ -6667,6 +6863,26 @@ msgid "" "an other object.\n" " " msgstr "" +"\n" +"Este módulo permite que você gerencie seus contatos\n" +"==============================================\n" +"\n" +"Ele permite que você definir:\n" +"     * Contatos não relacionados a um parceiro,\n" +"     * Contatos trabalhando em vários endereços (possivelmente para " +"parceiros diferentes),\n" +"     * Contatos com funções possivelmente diferentes para cada um dos " +"endereços do seu trabalho\n" +"\n" +"Ele também adiciona novos itens de menu localizado na\n" +"     Compras / Livro de Endereços / Contatos\n" +"     Vendas / Livro de Endereços / Contatos\n" +"\n" +"Preste atenção que este módulo converte os endereços existentes em " +"\"endereços + contatos\". Isso significa que alguns campos dos endereços vai " +"estar ausente (como o nome do contato), uma vez que estes devem ser " +"definidos em um outro objeto.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.act_res_partner_event @@ -8017,6 +8233,14 @@ msgid "" "that exceeds minimum amount set by configuration wizard.\n" " " msgstr "" +"\n" +"Dupla-validação para compras superiores a quantidade mínima.\n" +"================================================== =======\n" +"\n" +"Este módulo modifica o fluxo de trabalho de compra, a fim de validar " +"compras\n" +"que exceder o valor mínimo fixado pelo assistente de configuração.\n" +" " #. module: base #: field:res.currency,rounding:0 @@ -14393,6 +14617,15 @@ msgid "" "plans.\n" " " msgstr "" +"\n" +"O módulo base para gerenciar a distribuição analítica e ordens de compra.\n" +"================================================== ==================\n" +"\n" +"Permite que o usuário manter planos de análise diversas. Estes permitem-lhe " +"dividir\n" +"uma linha em um pedido de compra de fornecedores em várias contas e planos " +"analíticos.\n" +" " #. module: base #: field:res.company,vat:0 diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po index 8576dce8f84..8f673e6138f 100644 --- a/openerp/addons/base/i18n/ro.po +++ b/openerp/addons/base/i18n/ro.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:40+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po index 82e7869a7ce..57175fa581f 100644 --- a/openerp/addons/base/i18n/ru.po +++ b/openerp/addons/base/i18n/ru.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-25 04:44+0000\n" -"X-Generator: Launchpad (build 16019)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po index b119359ec95..ec4981d65af 100644 --- a/openerp/addons/base/i18n/sk.po +++ b/openerp/addons/base/i18n/sk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:40+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po index 3abc2191ca1..6f5fea1a902 100644 --- a/openerp/addons/base/i18n/sl.po +++ b/openerp/addons/base/i18n/sl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po index c73b4e69686..f0ae2c5c50f 100644 --- a/openerp/addons/base/i18n/sq.po +++ b/openerp/addons/base/i18n/sq.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:35+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:10+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po index 2c32b7fd61a..d1da84e99c3 100644 --- a/openerp/addons/base/i18n/sr.po +++ b/openerp/addons/base/i18n/sr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:40+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:15+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po index 98d86237ce2..c7ead346847 100644 --- a/openerp/addons/base/i18n/sr@latin.po +++ b/openerp/addons/base/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:19+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po index 5c6ffb07321..693f4042c34 100644 --- a/openerp/addons/base/i18n/sv.po +++ b/openerp/addons/base/i18n/sv.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po index 455fe808228..5c973f1c0f8 100644 --- a/openerp/addons/base/i18n/th.po +++ b/openerp/addons/base/i18n/th.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po index 78e31dfc564..7c81a8298b4 100644 --- a/openerp/addons/base/i18n/tlh.po +++ b/openerp/addons/base/i18n/tlh.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po index c51ba45a1b4..890ce6474dc 100644 --- a/openerp/addons/base/i18n/tr.po +++ b/openerp/addons/base/i18n/tr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po index 792501814dd..84c39337199 100644 --- a/openerp/addons/base/i18n/uk.po +++ b/openerp/addons/base/i18n/uk.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:41+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po index 5163f59f157..58b2ffd8cdf 100644 --- a/openerp/addons/base/i18n/ur.po +++ b/openerp/addons/base/i18n/ur.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:16+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po index 26fce52ba3f..b071215c34c 100644 --- a/openerp/addons/base/i18n/vi.po +++ b/openerp/addons/base/i18n/vi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po index a8f2da01e50..b6261de14ba 100644 --- a/openerp/addons/base/i18n/zh_CN.po +++ b/openerp/addons/base/i18n/zh_CN.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po index 46f538a7125..daf05edeaac 100644 --- a/openerp/addons/base/i18n/zh_HK.po +++ b/openerp/addons/base/i18n/zh_HK.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:17+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po index 9f7c2baf4ef..4951c2fff9a 100644 --- a/openerp/addons/base/i18n/zh_TW.po +++ b/openerp/addons/base/i18n/zh_TW.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-20 04:42+0000\n" -"X-Generator: Launchpad (build 15985)\n" +"X-Launchpad-Export-Date: 2012-10-04 05:18+0000\n" +"X-Generator: Launchpad (build 16061)\n" #. module: base #: model:res.country,name:base.sh From 3856dcd5f1d03fb953d2cab7d17217286d5585e1 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Thu, 4 Oct 2012 05:33:37 +0000 Subject: [PATCH 528/726] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20121004053337-541ss7diwg0ae2lw --- addons/web_calendar/i18n/fa.po | 144 +++++++++++++++++++++++++++++++++ addons/web_diagram/i18n/fa.po | 81 +++++++++++++++++++ addons/web_gantt/i18n/fa.po | 28 +++++++ addons/web_graph/i18n/fa.po | 98 ++++++++++++++++++++++ addons/web_kanban/i18n/fa.po | 66 +++++++++++++++ 5 files changed, 417 insertions(+) create mode 100644 addons/web_calendar/i18n/fa.po create mode 100644 addons/web_diagram/i18n/fa.po create mode 100644 addons/web_gantt/i18n/fa.po create mode 100644 addons/web_graph/i18n/fa.po create mode 100644 addons/web_kanban/i18n/fa.po diff --git a/addons/web_calendar/i18n/fa.po b/addons/web_calendar/i18n/fa.po new file mode 100644 index 00000000000..7c322bdc2ae --- /dev/null +++ b/addons/web_calendar/i18n/fa.po @@ -0,0 +1,144 @@ +# Persian translation for openerp-web +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openerp-web package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-10-03 10:24+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Persian \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-04 05:33+0000\n" +"X-Generator: Launchpad (build 16061)\n" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:11 +msgid "Calendar" +msgstr "تقویم" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:70 +msgid "Filter" +msgstr "فیلتر" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:144 +msgid "Today" +msgstr "امروز" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:145 +msgid "Day" +msgstr "روز" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:146 +msgid "Week" +msgstr "هفته" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:147 +msgid "Month" +msgstr "ماه" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:148 +msgid "New event" +msgstr "رویداد جدید" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:149 +msgid "Save" +msgstr "ذخیره" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:150 +msgid "Cancel" +msgstr "لغو کردن" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:151 +msgid "Details" +msgstr "جزئیات ‌" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:152 +msgid "Edit" +msgstr "ویرایش" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:153 +msgid "Delete" +msgstr "حذف" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:155 +msgid "Event will be deleted permanently, are you sure?" +msgstr "رویداد حذف خواهد شد. آیا مطمئن هستید؟" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:156 +#: addons/web_calendar/static/src/js/calendar.js:169 +msgid "Description" +msgstr "توضیحات" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:157 +msgid "Time period" +msgstr "بازه زمانی" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:158 +msgid "Full day" +msgstr "تمام روز" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:161 +msgid "Do you want to edit the whole set of repeated events?" +msgstr "آیا میخواهید مجموعه کامل رویدادهای تکراری را ویرایش کنید؟" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:162 +msgid "Repeat event" +msgstr "تکرار رویداد" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:163 +msgid "Disabled" +msgstr "غیرفعال" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:164 +msgid "Enabled" +msgstr "فعال" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:167 +#: addons/web_calendar/static/src/js/calendar.js:175 +msgid "Agenda" +msgstr "دستور کار" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:168 +msgid "Date" +msgstr "تاریخ" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:172 +msgid "Year" +msgstr "سال" + +#. openerp-web +#: addons/web_calendar/static/src/xml/web_calendar.xml:5 +#: addons/web_calendar/static/src/xml/web_calendar.xml:6 +msgid " " +msgstr "" + +#~ msgid "Navigator" +#~ msgstr "هدایتگر" diff --git a/addons/web_diagram/i18n/fa.po b/addons/web_diagram/i18n/fa.po new file mode 100644 index 00000000000..061e2ca2950 --- /dev/null +++ b/addons/web_diagram/i18n/fa.po @@ -0,0 +1,81 @@ +# Persian translation for openerp-web +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openerp-web package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-10-03 10:07+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Persian \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-04 05:33+0000\n" +"X-Generator: Launchpad (build 16061)\n" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:11 +msgid "Diagram" +msgstr "نمودار" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:165 +msgid "Are you sure?" +msgstr "آیا مطمئن هستید؟" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:195 +msgid "" +"Deleting this node cannot be undone.\n" +"It will also delete all connected transitions.\n" +"\n" +"Are you sure ?" +msgstr "" +"عمل حذف برگشت پذیر نیست.\n" +"همچنین تمام اتصال ها را نیز حذف میکند.\n" +"\n" +"آیا مطمئن هستید؟" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:213 +msgid "" +"Deleting this transition cannot be undone.\n" +"\n" +"Are you sure ?" +msgstr "" +"حذف این انتقال برگشت پذیر نیست.\n" +"\n" +"آیا از خذف مطمئن هستید؟" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:224 +#: addons/web_diagram/static/src/js/diagram.js:257 +msgid "Activity" +msgstr "فعالیت" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:232 +#: addons/web_diagram/static/src/js/diagram.js:296 +msgid "Open: " +msgstr "باز: " + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:262 +#: addons/web_diagram/static/src/js/diagram.js:314 +msgid "Create:" +msgstr "ایجاد کردن" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:289 +#: addons/web_diagram/static/src/js/diagram.js:308 +msgid "Transition" +msgstr "انتقال" + +#. openerp-web +#: addons/web_diagram/static/src/xml/base_diagram.xml:6 +msgid "New Node" +msgstr "گره جدید" diff --git a/addons/web_gantt/i18n/fa.po b/addons/web_gantt/i18n/fa.po new file mode 100644 index 00000000000..1312a750199 --- /dev/null +++ b/addons/web_gantt/i18n/fa.po @@ -0,0 +1,28 @@ +# Persian translation for openerp-web +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openerp-web package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-10-03 10:11+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Persian \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-04 05:33+0000\n" +"X-Generator: Launchpad (build 16061)\n" + +#. openerp-web +#: addons/web_gantt/static/src/js/gantt.js:11 +msgid "Gantt" +msgstr "گانت" + +#. openerp-web +#: addons/web_gantt/static/src/xml/web_gantt.xml:10 +msgid "Create" +msgstr "ایجاد کردن" diff --git a/addons/web_graph/i18n/fa.po b/addons/web_graph/i18n/fa.po new file mode 100644 index 00000000000..c21101d1941 --- /dev/null +++ b/addons/web_graph/i18n/fa.po @@ -0,0 +1,98 @@ +# Persian translation for openerp-web +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openerp-web package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-10-03 10:12+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Persian \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-04 05:33+0000\n" +"X-Generator: Launchpad (build 16061)\n" + +#. openerp-web +#: addons/web_graph/static/src/js/graph.js:19 +msgid "Graph" +msgstr "گراف" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:5 +msgid "Graph Options" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:7 +msgid "Graph Mode" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:11 +msgid "Pie" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:12 +msgid "Bars" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:14 +msgid "Lines" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:15 +msgid "Areas" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:18 +msgid "Radar" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:20 +msgid "Legend" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:24 +msgid "Hidden" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:25 +msgid "Inside" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:26 +msgid "Top" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:28 +msgid "Actions" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:32 +msgid "Switch Axis" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:33 +msgid "Show Data" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:34 +msgid "Download as PNG" +msgstr "" diff --git a/addons/web_kanban/i18n/fa.po b/addons/web_kanban/i18n/fa.po new file mode 100644 index 00000000000..77588970169 --- /dev/null +++ b/addons/web_kanban/i18n/fa.po @@ -0,0 +1,66 @@ +# Persian translation for openerp-web +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openerp-web package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-10-03 10:14+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Persian \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-04 05:33+0000\n" +"X-Generator: Launchpad (build 16061)\n" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:10 +msgid "Kanban" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:293 +msgid "Undefined" +msgstr "تعریف نشده" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:471 +msgid "Are you sure you want to delete this record ?" +msgstr "آیا از حذف این رکورد مطمئن هستید؟" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:839 +msgid "Create: " +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:41 +msgid "Show more... (" +msgstr "نمایش بیشتر" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:41 +msgid "remaining)" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:71 +msgid "Add" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:71 +msgid "or" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:72 +msgid "Cancel" +msgstr "" + +#~ msgid "Create" +#~ msgstr "ایجاد کردن" From 601568f5f9431338886aa1aeda240a7137f16173 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Oct 2012 08:42:15 +0200 Subject: [PATCH 529/726] [FIX] don't import empty cells at all rather than set them to False, to allow defaults handling to do its job before actually creating the record bzr revid: xmo@openerp.com-20121004064215-fqgir3ovmte2v438 --- openerp/osv/orm.py | 1 - openerp/tests/addons/test_impex/models.py | 10 ++++++++++ .../tests/addons/test_impex/tests/test_load.py | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 4f21a159cdd..b0b0fad88fa 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1501,7 +1501,6 @@ class BaseModel(object): for field, strvalue in record.iteritems(): if field in (None, 'id', '.id'): continue if not strvalue: - converted[field] = False continue # In warnings and error messages, use translated string as diff --git a/openerp/tests/addons/test_impex/models.py b/openerp/tests/addons/test_impex/models.py index 3c85b56fff7..50340082d08 100644 --- a/openerp/tests/addons/test_impex/models.py +++ b/openerp/tests/addons/test_impex/models.py @@ -123,3 +123,13 @@ class Many2ManyChild(orm.Model): , context=context) if isinstance(name, basestring) and name.split(':')[0] == self._name else []) + +class SelectionWithDefault(orm.Model): + _name = 'export.selection.withdefault' + + _columns = { + 'value': fields.selection([(1, "Foo"), (2, "Bar")], required=True), + } + _defaults = { + 'value': 2, + } diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index 18b26a16354..65c4b6e9e57 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -474,6 +474,21 @@ class test_selection(ImporterCase): u"Value '42' not found in selection field 'unknown'", moreinfo="Foo Bar Qux 4".split())]) +class test_selection_with_default(ImporterCase): + model_name = 'export.selection.withdefault' + + def test_skip_empty(self): + """ Empty cells should be entirely skipped so that default values can + be inserted by the ORM + """ + result = self.import_(['value'], [['']]) + self.assertFalse(result['messages']) + self.assertEqual(len(result['ids']), 1) + + self.assertEqual( + values(self.read()), + [2]) + class test_selection_function(ImporterCase): model_name = 'export.selection.function' translations_fr = [ From c51c904e7d45b3c1aba82dd1217c6258a3021b17 Mon Sep 17 00:00:00 2001 From: "vta vta@openerp.com" <> Date: Thu, 4 Oct 2012 09:00:55 +0200 Subject: [PATCH 530/726] [FIX] Fixed bug in 'SelectCreatePopup', it didn't returned the corrrect stuff (r.result->r). bzr revid: vta@openerp.com-20121004070055-dq6kvaqlph6q1ei6 --- addons/web/static/src/js/view_form.js | 4 ++-- addons/web/static/src/js/views.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index bf6b869482b..1c32d5ef63e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2081,7 +2081,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w var self = this; var trans = new instance.web.DataSet(this, 'ir.translation'); return trans.call_button('translate_fields', [this.view.dataset.model, this.view.datarecord.id, this.name, this.view.dataset.get_context()]).then(function(r) { - self.do_action(r.result); + self.do_action(r); }); }, }); @@ -4282,7 +4282,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({ this.dataset.create_function = function(data, sup) { var fct = self.options.create_function || sup; return fct.call(this, data).then(function(r) { - self.created_elements.push(r.result); + self.created_elements.push(r); }); }; this.dataset.write_function = function(id, data, options, sup) { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 2fff0e7b683..7b5fcc70289 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1190,7 +1190,7 @@ instance.web.View = instance.web.Widget.extend({ var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {}); var handler = function (r) { - var action = r.result; + var action = r; if (action && action.constructor == Object) { var ncontext = new instance.web.CompoundContext(context); if (record_id) { From 29a53e19546570b97932d163a0c2d0a2acf4a7ff Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Oct 2012 09:46:10 +0200 Subject: [PATCH 531/726] [REV] header template extraction bzr revid: xmo@openerp.com-20121004074610-o2wk9nspzgqjj4y1 --- addons/web/static/src/xml/base.xml | 6 ---- doc/images/templates/ui.Header.png | Bin 2844 -> 0 bytes doc/index.rst | 2 -- doc/templates.rst | 45 ----------------------------- 4 files changed, 53 deletions(-) delete mode 100644 doc/images/templates/ui.Header.png delete mode 100644 doc/templates.rst diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index dfe86036c45..cead483ead6 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -2,12 +2,6 @@ - -
                              - -
                              -
                              -
                              diff --git a/doc/images/templates/ui.Header.png b/doc/images/templates/ui.Header.png deleted file mode 100644 index c5a1e2a8ef87c2d50eaf371dc07152aa436b7820..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2844 zcmX|DXFMBPAEwpU9;I5fwYj~jHjP<(kEm5@Bt~P`OeMsOO{-L0qZNCE8Y!jJrrg?M z)K)Y046PvE^j`1#;hf+3@chm>|Mfgi++&b7BONCl1qB78u8xKY1qEe3`OHmog}keC zYu8aw&@Jg|sG1?Bw%?tYn&LUT5BXqS7)Kf7D#5br?UJe@S$U@J*b!F+mu==_|I#Dy zt_VCnA0`w(UjDdn`-P)7CsJ1k@ zd*@hA?tCTH0vwMLip+hK5=^Daa%^u10?pO?6^jcAg?C`imQ#v&6#fM;1_&>RsSS0d45hjZf#A=%b~M(QRmg?xJ!eoVx~6=y?XU(%#(@_%(SkwbZ+!CzvkJm zB=p)&H2rhW>py1hUE;Lz_hZ-}xb64fN}FEXy$~L2h9(e~b;NVgZrFE}-pPKORoPEJVPMy7dC|dC^@rDw@v70DZ zP=TO+?2)CItW12raA>`+y121pjN-rfE~7xJS!HmITIL58&nz@v2voIo2mXy(775(x`lHwk`v4`-osH zwt+xEs;j4*pFf%p#^*pf7FVRr$^^h7K z1!D8x3##@nddL20)6QWhwM4w;!ElYHn%W6ru9SM-!C@pJ^lq=T?AU~$k=}<^lIXqY zvcxY#cf#RZJrJGJ-n>Na0llERHXtN7qC*Boq8 z%vFI=?ViGWcLfF}L8sim6Bie?I5~?v=e0(_d~i%kN;2#XBbV9!zUk7^n2qRaG8MIQ z`ui;g=1O0|tL8N7TnCozL)mLDX|E-pIn_62@!gL0F(^KILmF-3SnAUZF9C%oiX`dj zaKCc0Bi)ZH(B^mPPJ?S|j++UIxH=MBI@y=@`UW-SYl0U4`xF2nI zPK3P1R{A006RN1xuiKP{BK4d8_5^;0K~RiF(j1zilgO&dcdZ#}A2tR5EQ# zrI?HyJwaUya#)E>d6S;bL|w?H_v<`(SkXpGT)$wo zK&h`n)pX--IOeLvhiGXrc11;rOmHL`M67;-(N@Dp+^FLdro}5NHq=^5O0F#ly`)81 zdRQXhlk@WzgWn-|zk1Xs_b6W8#GVn;;FX?;IND$^8Yt!W7@+1cD<8^x?hBchsOLVX zQ*M#;*hfWR4L84dQ^o*KSCo``3JP@dub=nioAereFjR`I=QC_=@0!LyW zdcZ|`;aJjMp-YXt_S1SKJfGJ;{K=NFI=t5Cs9hcxZ)#Pk<;-f%9$?30si~`)Pqg^lC=?b|yks&xt*`UDG zqWg=!+zN>hPu#Y=*zFqTJL_(l9B~nq3uxJ>Z7?BuW~7*o@jp_)auZCAPQyfcUSeYN)>fcRSlGyB zIbS~@3*^k>7!fT|ZJ45Wnhq&>o2H9InzQQO5?$Lc$qgWyg_q>1-!mQ4X|T3hUK<41 zLet`YGfCmd`dht~=0g3$v$KQQ8M?WUX)t?3J>&Q|lbP9DDylt2MY`G90EEkIjcdEz zP}Qg^omdxkL$+A(2 zOaBX2mOALU^TvH;j+^r86AL)rkuY}Xoi{u0C)QZb@&!|goso3QOs0MArc_ULeYkjS z^O>OdRcV_>{!UEeOkiIxAWO?}jOA^u{mYg<5Sy3;h8VQC^9xnh_IIwv>%1&W@2!9rwIJwGq3b* zAS(z0NwBF{I(*lBUVFYayc!#OAYx57GlKwwfv1AQwa*!mKMxw4GQOSSa7odqA3x5< z%7%SxE_s84#DH^#!F0Ye!w_6y>e5)NMmCip4)lN8J&AF?mbpW2(pr73XW0NmSEoDp zMyr`DRFYA0WRa7>TWqyE{p9VWdKQzhdl%HNa(L5_LsGAASxSbL%z%A>SqLQfsG-tp zU}LOaRFr8W`isJy)i|f-80yRuH2POuIgxmz27#cnA>nm!blC&HaVNgiIw!_~)e5U9 z3D0b9ZnJ`dWn{p@9_AW(a;BYdluO(U^jBn<3?katMh4Kqd2&eEQ1r=n3NG@K``mU5 zNYN-Ytn;@w20#V(vC_~=OKero(`qgB8yqWp>h{J)j#p*8x|*~i+HSgbb8wa7U$sE} z#ZS|&B&_&DK-gdGsqd@)0hrG>n6H&3wEpv+x*FZ*8DVE<>fq@p6~ckg`Cf+y{HODo z?4|#x`Nxc5%!KM~Nbo<4Zx{{2I=c^6=qnhU@h?*!@DO;|+c#TIV3%+r*-dSAw13f$ z{OSb>Z3>#Z71{|&$W*Cf5#?2(vHUTabJ_kUyQLi7ar&o12=6GbHZ}E1qwHx#qW9A*Gr+R3DT%gvqSwCt!a{b diff --git a/doc/index.rst b/doc/index.rst index a6d2248cedf..6a0d8dee2d4 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -22,8 +22,6 @@ Contents: list-view form-notes - templates - guides/client-action Indices and tables diff --git a/doc/templates.rst b/doc/templates.rst deleted file mode 100644 index 3f7a3a18743..00000000000 --- a/doc/templates.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. highlight:: xml - -Generic templates -================= - -Generic template names should be prefixed by ``ui.`` to indicate their -special role. - -Global Header: ``ui.Header`` ----------------------------- - -Role -++++ - -This template is mostly dedicated to client actions taking over the -whole content area, and full-HTML form views (especially those opening -in the ``inline`` target). - -It is used to display a buttons container (and can also be used for -status bars). The buttons should simply be placed inside the -``ui.Header`` body. - -Arguments -+++++++++ - -The template only uses its body as argument. - -Example -+++++++ - -:: - - -