# -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Joël Grand-Guillaume
#    Copyright 2010-2013 Camptocamp 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 <http://www.gnu.org/licenses/>.
#
##############################################################################

from itertools import product
from openerp.osv import orm, fields
import openerp.addons.decimal_precision as dp


class account_analytic_account(orm.Model):
    _inherit = 'account.analytic.account'

    def _debit_credit_bal_qtty(self, cr, uid, ids, fields, arg, context=None):
        """Replace the original amount column by aa_amount_currency"""
        if context is None:
            context = {}
        child_ids = self.search(cr, uid,
                                [('parent_id', 'child_of', ids)],
                                context=context)
        sums = {}
        if not child_ids:
            return sums
        for child_id, field in product(child_ids, fields):
            sums.setdefault(child_id, {})[field] = 0.0

        where_date = ''
        where_clause_args = [tuple(child_ids)]
        if context.get('from_date'):
            where_date += " AND l.date >= %s"
            where_clause_args += [context['from_date']]
        if context.get('to_date'):
            where_date += " AND l.date <= %s"
            where_clause_args += [context['to_date']]
        cr.execute("""
              SELECT a.id,
                     sum(
                         CASE WHEN l.aa_amount_currency > 0
                         THEN l.aa_amount_currency
                         ELSE 0.0
                         END
                          ) as debit,
                     sum(
                         CASE WHEN l.aa_amount_currency < 0
                         THEN -l.aa_amount_currency
                         ELSE 0.0
                         END
                          ) as credit,
                     COALESCE(SUM(l.aa_amount_currency),0) AS balance,
                     COALESCE(SUM(l.unit_amount),0) AS quantity
              FROM account_analytic_account a
                  LEFT JOIN account_analytic_line l ON (a.id = l.account_id)
              WHERE a.id IN %s
              """ + where_date + """
              GROUP BY a.id""", where_clause_args)
        for ac_id, debit, credit, balance, quantity in cr.fetchall():
            sums[ac_id] = {'debit': debit,
                           'credit': credit,
                           'balance': balance,
                           'quantity': quantity}
        return self._compute_level_tree(cr, uid, ids, child_ids, sums,
                                        ['debit', 'credit',
                                         'balance', 'quantity'],
                                        context)

    _columns = {
        'balance': fields.function(_debit_credit_bal_qtty,
                                   type='float',
                                   string='Balance',
                                   multi='debit_credit_bal_qtty',
                                   digits_compute=dp.get_precision('Account')),
        'debit': fields.function(_debit_credit_bal_qtty,
                                 type='float',
                                 string='Debit',
                                 multi='debit_credit_bal_qtty',
                                 digits_compute=dp.get_precision('Account')),
        'credit': fields.function(_debit_credit_bal_qtty,
                                  type='float',
                                  string='Credit',
                                  multi='debit_credit_bal_qtty',
                                  digits_compute=dp.get_precision('Account')),
        'quantity': fields.function(_debit_credit_bal_qtty,
                                    type='float',
                                    string='Quantity',
                                    multi='debit_credit_bal_qtty'),
    }

    # We remove the currency constraint cause we want to let the user
    # choose another currency than the company one. Don't be able to
    # override properly this constraints :(
    def check_currency(self, cr, uid, ids, context=None):
        return True

    def check_recursion(self, cr, uid, ids, parent=None):
        return super(account_analytic_account, self)._check_recursion(
            cr, uid, ids, parent=parent)

    _constraints = [
        (check_recursion,
         'Error. You can not create recursive analytic accounts.',
         ['parent_id']),
        (check_currency,
         'Error. The currency has to be the same as the currency of '
         'the selected company.',
         ['currency_id', 'company_id']),
    ]

@@ -3428,24 +3428,791 @@
   context)%0A%0A
+    def _set_company_currency(self, cr, uid, ids, name, value, arg, context=None):%0A        if isinstance(ids, (int, long)):%0A            ids = %5Bids%5D%0A        if value:%0A            return cr.execute(%22%22%22update account_analytic_account set currency_id=%25s%0A                                 where id in %25s%22%22%22,%0A                              (value, (tuple(ids)), ))%0A%0A    def _currency(self, cr, uid, ids, field_name, arg, context=None):%0A        result = %7B%7D%0A        for rec in self.browse(cr, uid, ids, context=context):%0A            result%5Brec.id%5D = rec.currency_id.id%0A        return result%0A%0A    def _get_analytic_account(self, cr, uid, ids, context=None):%0A        return super(account_analytic_account, self)._get_analytic_account(%0A            cr, uid, ids, context=context)%0A%0A
     _columns
@@ -5352,16 +5352,399 @@
 qtty'),%0A
+        # We overwrite function field currency_id to set a currency different%0A        # from the one specified in the company%0A        'currency_id': fields.function(_currency, fnct_inv=_set_company_currency,%0A            store=%7B%0A                'res.company': (_get_analytic_account, %5B'currency_id'%5D, 10),%0A            %7D, string='Currency', type='many2one', relation='res.currency'),%0A%0A
     %7D%0A%0A 

Allow to set an different currency from the one specified in the company