From d8500896c936e10fdf157492aa2ed2787b47fca7 Mon Sep 17 00:00:00 2001 From: Joel Grand-Guillaume Date: Wed, 23 Dec 2009 10:55:20 +0100 Subject: [PATCH] [IMP] Add trigger on account.analytic.line for currency change [IMP] Refactoring the _balance_calc in project.py [FIX] Use the new refactored funtion to compute indicator in right the currency according to each level of analytical account bzr revid: joel.grandguillaume@camptocamp.com-20091223095520-8gsqff2w7z0yrc7z --- addons/account/account_analytic_line.py | 14 +++-- addons/account/project/project.py | 52 ++++++++++--------- .../account_analytic_analysis.py | 43 +++------------ 3 files changed, 45 insertions(+), 64 deletions(-) diff --git a/addons/account/account_analytic_line.py b/addons/account/account_analytic_line.py index 473a60f921b..34a422579fe 100644 --- a/addons/account/account_analytic_line.py +++ b/addons/account/account_analytic_line.py @@ -81,14 +81,18 @@ class account_analytic_line(osv.osv): 'currency_id': fields.function(_get_account_currency, method=True, type='many2one', relation='res.currency', string='Account currency', store={ 'account.analytic.account': (_get_account_line, ['company_id'], 50), + 'account.analytic.line': (lambda self,cr,uid,ids,c={}: ids, ['amount','unit_amount'],10), }, - help="The related account currency if not equal to the company one."), + # multi='all', + help="The related account currency if not equal to the company one."), 'company_id': fields.many2one('res.company','Company',required=True), 'amount_currency': fields.function(_amount_currency, method=True, digits=(16, int(config['price_accuracy'])), string='Amount currency', - store={ - 'account.analytic.account': (_get_account_line, ['company_id'], 50), - }, - help="The amount expressed in the related account currency if not equal to the company one."), + store={ + 'account.analytic.account': (_get_account_line, ['company_id'], 50), + 'account.analytic.line': (lambda self,cr,uid,ids,c={}: ids, ['amount','unit_amount'],10), + }, + # multi='all', + help="The amount expressed in the related account currency if not equal to the company one."), 'ref': fields.char('Reference', size=32), } _defaults = { diff --git a/addons/account/project/project.py b/addons/account/project/project.py index 5fa9e8c96ff..38d7e63ed30 100644 --- a/addons/account/project/project.py +++ b/addons/account/project/project.py @@ -33,6 +33,32 @@ class account_analytic_account(osv.osv): _name = 'account.analytic.account' _description = 'Analytic Accounts' + def _compute_currency_for_level_tree(self, cr, uid, ids, ids2, res, acc_set, context={}): + # Handle multi-currency on each level of analytic account + # This is a refactoring of _balance_calc computation + cr.execute("SELECT a.id, r.currency_id FROM account_analytic_account a INNER JOIN res_company r ON (a.company_id = r.id) where a.id in (%s)" % acc_set) + currency= dict(cr.fetchall()) + res_currency= self.pool.get('res.currency') + for id in ids: + if id not in ids2: + continue + for child in self.search(cr, uid, [('parent_id', 'child_of', [id])]): + if child <> id: + res.setdefault(id, 0.0) + if currency[child]<>currency[id]: + res[id] += res_currency.compute(cr, uid, currency[child], currency[id], res.get(child, 0.0), context=context) + else: + res[id] += res.get(child, 0.0) + + cur_obj = res_currency.browse(cr,uid,currency.values(),context) + cur_obj = dict([(o.id, o) for o in cur_obj]) + for id in ids: + if id in ids2: + res[id] = res_currency.round(cr,uid,cur_obj[currency[id]],res.get(id,0.0)) + + return dict([(i, res[i]) for i in ids ]) + + def _credit_calc(self, cr, uid, ids, name, arg, context={}): acc_set = ",".join(map(str, ids)) @@ -86,30 +112,8 @@ class account_analytic_account(osv.osv): for account_id, sum in cr.fetchall(): res[account_id] = sum - cr.execute("SELECT a.id, r.currency_id FROM account_analytic_account a INNER JOIN res_company r ON (a.company_id = r.id) where a.id in (%s)" % acc_set) - - currency= dict(cr.fetchall()) - - res_currency= self.pool.get('res.currency') - for id in ids: - if id not in ids2: - continue - for child in self.search(cr, uid, [('parent_id', 'child_of', [id])]): - if child <> id: - res.setdefault(id, 0.0) - if currency[child]<>currency[id]: - res[id] += res_currency.compute(cr, uid, currency[child], currency[id], res.get(child, 0.0), context=context) - else: - res[id] += res.get(child, 0.0) - - cur_obj = res_currency.browse(cr,uid,currency.values(),context) - cur_obj = dict([(o.id, o) for o in cur_obj]) - for id in ids: - if id in ids2: - res[id] = res_currency.round(cr,uid,cur_obj[currency[id]],res.get(id,0.0)) - - return dict([(i, res[i]) for i in ids ]) - + return self._compute_currency_for_level_tree(cr, uid, ids, ids2, res, acc_set, context) + def _quantity_calc(self, cr, uid, ids, name, arg, context={}): #XXX must convert into one uom res = {} diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index 425cde301d3..e623b1c94f7 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -35,7 +35,7 @@ class account_analytic_account(osv.osv): ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)]) if ids2: acc_set = ",".join(map(str, ids2)) - cr.execute("select account_analytic_line.account_id, COALESCE(sum(amount),0.0) \ + cr.execute("select account_analytic_line.account_id, COALESCE(sum(amount_currency),0.0) \ from account_analytic_line \ join account_analytic_journal \ on account_analytic_line.journal_id = account_analytic_journal.id \ @@ -44,15 +44,8 @@ class account_analytic_account(osv.osv): group by account_analytic_line.account_id" % acc_set) for account_id, sum in cr.fetchall(): res[account_id] = round(sum,2) - for obj_id in ids: - res.setdefault(obj_id, 0.0) - for child_id in self.search(cr, uid, - [('parent_id', 'child_of', [obj_id])]): - if child_id != obj_id: - res[obj_id] += res.get(child_id, 0.0) - for id in ids: - res[id] = round(res.get(id, 0.0),2) - return res + + return self._compute_currency_for_level_tree(cr, uid, ids, ids2, res, acc_set, context) def _ca_to_invoice_calc(self, cr, uid, ids, name, arg, context={}): res = {} @@ -165,38 +158,18 @@ class account_analytic_account(osv.osv): ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)]) if ids2: acc_set = ",".join(map(str, ids2)) - cr.execute("""select account_analytic_line.account_id,COALESCE(sum(amount),0.0) \ - from account_analytic_line \ - join account_analytic_journal \ - on account_analytic_line.journal_id = account_analytic_journal.id \ - where account_analytic_line.account_id IN (%s) \ - and amount<0 \ - and amount_currency=0.0 \ - GROUP BY account_analytic_line.account_id"""%acc_set) - for account_id, sum in cr.fetchall(): - res[account_id] = round(sum,2) cr.execute("""select account_analytic_line.account_id,COALESCE(sum(amount_currency),0.0) \ from account_analytic_line \ join account_analytic_journal \ on account_analytic_line.journal_id = account_analytic_journal.id \ where account_analytic_line.account_id IN (%s) \ - and amount_currency<0 \ + and amount<0 \ + GROUP BY account_analytic_line.account_id"""%acc_set) for account_id, sum in cr.fetchall(): - if res.has_key(account_id): - res[account_id] += round(sum,2) - else: - res[account_id] = round(sum,2) - for obj_id in ids: - res.setdefault(obj_id, 0.0) - for child_id in self.search(cr, uid, - [('parent_id', 'child_of', [obj_id])]): - if child_id != obj_id: - res[obj_id] += res.get(child_id, 0.0) - for id in ids: - res[id] = round(res.get(id, 0.0),2) - return res - + res[account_id] = round(sum,2) + return self._compute_currency_for_level_tree(cr, uid, ids, ids2, res, acc_set, context) + def _ca_theorical_calc(self, cr, uid, ids, name, arg, context={}): res = {} res2 = {}