[IMP] Account : Analytic Account report following parental relationship approach...
[odoo/odoo.git] / addons / account / project / report / analytic_balance.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution   
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 import pooler
24 import time
25 from report import report_sxw
26
27
28 class account_analytic_balance(report_sxw.rml_parse):
29     def __init__(self, cr, uid, name, context):
30         super(account_analytic_balance, self).__init__(cr, uid, name, context)
31         self.localcontext.update( {
32             'time': time,
33             'get_objects': self._get_objects,
34             'lines_g': self._lines_g,
35             'move_sum': self._move_sum,
36 #            'move_sum_debit': self._move_sum_debit,
37 #            'move_sum_credit': self._move_sum_credit,
38             'sum_all': self._sum_all,
39 #            'sum_debit': self._sum_debit,
40 #            'sum_credit': self._sum_credit,
41             'sum_balance': self._sum_balance,
42 #            'sum_quantity': self._sum_quantity,
43             'move_sum_balance': self._move_sum_balance,
44 #            'move_sum_quantity': self._move_sum_quantity,
45         })
46         self.acc_ids = []
47         self.read_data = []
48         self.empty_acc = False
49         self.acc_data_dict = {}# maintains a relation with an account with its successors.
50         self.acc_sum_list = []# maintains a list of all ids
51         
52     def get_children(self, ids):
53         ids2 = []
54         read_data = self.pool.get('account.analytic.account').read(self.cr, self.uid, ids,['child_ids','code','complete_name','balance'])
55         for data in read_data:
56             if (data['id'] not in self.acc_ids):
57                 inculde_empty =  True
58                 if (not self.empty_acc) and data['balance'] == 0.00:
59                     inculde_empty = False
60                 if inculde_empty:    
61                     self.acc_ids.append(data['id'])
62                     self.read_data.append(data)
63                     if data['child_ids']:
64                         res = self.get_children(data['child_ids'])    
65         return True        
66         
67         
68     def _get_objects(self, empty_acc):
69         if self.read_data:
70             return self.read_data
71         self.empty_acc = empty_acc
72         self.read_data = []
73         self.get_children(self.ids)
74         
75         return self.read_data
76     
77     def _lines_g(self, account_id, date1, date2):
78         account_analytic_obj = self.pool.get('account.analytic.account')
79         ids = account_analytic_obj.search(self.cr, self.uid,
80                 [('parent_id', 'child_of', [account_id])])
81         self.cr.execute("SELECT aa.name AS name, aa.code AS code, \
82                     sum(aal.amount) AS balance, sum(aal.unit_amount) AS quantity \
83                 FROM account_analytic_line AS aal, account_account AS aa \
84                 WHERE (aal.general_account_id=aa.id) \
85                     AND (aal.account_id in (" + ','.join(map(str, ids)) + "))\
86                     AND (date>=%s) AND (date<=%s) AND aa.active \
87                 GROUP BY aal.general_account_id, aa.name, aa.code, aal.code \
88                 ORDER BY aal.code", (date1, date2))
89         res = self.cr.dictfetchall()
90         
91         for r in res:
92             if r['balance'] > 0:
93                 r['debit'] = r['balance']
94                 r['credit'] = 0.0
95             elif r['balance'] < 0:
96                 r['debit'] = 0.0
97                 r['credit'] = -r['balance']
98             else:
99                 r['balance'] == 0
100                 r['debit'] = 0.0
101                 r['credit'] = 0.0
102         return res
103     
104     def _move_sum(self, account_id, date1, date2, option):
105         if account_id not in self.acc_data_dict:
106             account_analytic_obj = self.pool.get('account.analytic.account')
107             ids = account_analytic_obj.search(self.cr, self.uid,[('parent_id', 'child_of', [account_id])])
108             self.acc_data_dict[account_id] = ids
109         else:
110             ids = self.acc_data_dict[account_id]
111         
112         if option == "credit" :
113             self.cr.execute("SELECT -sum(amount) FROM account_analytic_line \
114                     WHERE account_id in ("+ ','.join(map(str, ids)) +") \
115                         AND date>=%s AND date<=%s AND amount<0",
116                     (date1, date2))
117         elif option == "debit" :
118             self.cr.execute("SELECT sum(amount) FROM account_analytic_line \
119                     WHERE account_id in ("+ ','.join(map(str, ids)) +") \
120                         AND date>=%s AND date<=%s AND amount>0",
121                     (date1, date2))
122         elif option == "quantity" :
123             self.cr.execute("SELECT sum(unit_amount) FROM account_analytic_line \
124                 WHERE account_id in ("+ ','.join(map(str, ids)) +") \
125                     AND date>=%s AND date<=%s",
126                 (date1, date2))
127         return self.cr.fetchone()[0] or 0.0
128         
129
130 #    def _move_sum_debit(self, account_id, date1, date2):
131 #        account_analytic_obj = self.pool.get('account.analytic.account')
132 #        ids = account_analytic_obj.search(self.cr, self.uid,
133 #                [('parent_id', 'child_of', [account_id])])
134 #        self.cr.execute("SELECT sum(amount) \
135 #                FROM account_analytic_line \
136 #                WHERE account_id in ("+ ','.join(map(str, ids)) +") \
137 #                    AND date>=%s AND date<=%s AND amount>0",
138 #                (date1, date2))
139 #        return self.cr.fetchone()[0] or 0.0
140 #
141 #    def _move_sum_credit(self, account_id, date1, date2):
142 #        account_analytic_obj = self.pool.get('account.analytic.account')
143 #        ids = account_analytic_obj.search(self.cr, self.uid,
144 #                [('parent_id', 'child_of', [account_id])])
145 #        self.cr.execute("SELECT -sum(amount) \
146 #                FROM account_analytic_line \
147 #                WHERE account_id in ("+ ','.join(map(str, ids)) +") \
148 #                    AND date>=%s AND date<=%s AND amount<0",
149 #                (date1, date2))
150 #        return self.cr.fetchone()[0] or 0.0
151 #    
152     def _move_sum_balance(self, account_id, date1, date2):
153         debit = self._move_sum(account_id, date1, date2, 'debit') 
154         credit = self._move_sum(account_id, date1, date2, 'credit')
155         return (debit-credit)
156     
157 #    def _move_sum_quantity(self, account_id, date1, date2):
158 #        account_analytic_obj = self.pool.get('account.analytic.account')
159 #        ids = account_analytic_obj.search(self.cr, self.uid,
160 #                [('parent_id', 'child_of', [account_id])])
161 #        self.cr.execute("SELECT sum(unit_amount) \
162 #                FROM account_analytic_line \
163 #                WHERE account_id in ("+ ','.join(map(str, ids)) +") \
164 #                    AND date>=%s AND date<=%s",
165 #                (date1, date2))
166 #        return self.cr.fetchone()[0] or 0.0
167
168     def _sum_all(self, accounts, date1, date2, option):
169         ids = map(lambda x: x['id'], accounts)
170         
171         if not len(ids):
172             return 0.0
173
174         if not self.acc_sum_list:
175             account_analytic_obj = self.pool.get('account.analytic.account')
176             ids2 = account_analytic_obj.search(self.cr, self.uid,[('parent_id', 'child_of', ids)])
177             self.acc_sum_list = ids2
178         else:
179             ids2 = self.acc_sum_list
180
181         if option == "debit" :
182             self.cr.execute("SELECT sum(amount) FROM account_analytic_line \
183                     WHERE account_id IN ("+','.join(map(str, ids2))+") \
184                         AND date>=%s AND date<=%s AND amount>0",
185                     (date1, date2))
186         elif option == "credit" :
187             self.cr.execute("SELECT -sum(amount) FROM account_analytic_line \
188                     WHERE account_id IN ("+','.join(map(str, ids2))+") \
189                         AND date>=%s AND date<=%s AND amount<0",
190                     (date1, date2))
191         elif option == "quantity" :
192             self.cr.execute("SELECT sum(unit_amount) FROM account_analytic_line \
193                     WHERE account_id IN ("+','.join(map(str, ids2))+") \
194                         AND date>=%s AND date<=%s",
195                     (date1, date2))
196         return self.cr.fetchone()[0] or 0.0
197
198     
199 #    def _sum_debit(self, accounts, date1, date2):
200 #        ids = map(lambda x: x['id'], accounts)
201 #        if not len(ids):
202 #            return 0.0
203 #        account_analytic_obj = self.pool.get('account.analytic.account')
204 #        ids2 = account_analytic_obj.search(self.cr, self.uid,
205 #                [('parent_id', 'child_of', ids)])
206 #        self.cr.execute("SELECT sum(amount) \
207 #                FROM account_analytic_line \
208 #                WHERE account_id IN ("+','.join(map(str, ids2))+") \
209 #                    AND date>=%s AND date<=%s AND amount>0",
210 #                (date1, date2))
211 #        return self.cr.fetchone()[0] or 0.0
212 #        
213 #    def _sum_credit(self, accounts, date1, date2):
214 #        ids = map(lambda x: x['id'], accounts)
215 #        if not len(ids):
216 #            return 0.0
217 #        ids = map(lambda x: x['id'], accounts)
218 #        account_analytic_obj = self.pool.get('account.analytic.account')
219 #        ids2 = account_analytic_obj.search(self.cr, self.uid,
220 #                [('parent_id', 'child_of', ids)])
221 #        self.cr.execute("SELECT -sum(amount) \
222 #                FROM account_analytic_line \
223 #                WHERE account_id IN ("+','.join(map(str, ids2))+") \
224 #                    AND date>=%s AND date<=%s AND amount<0",
225 #                (date1, date2))
226 #        return self.cr.fetchone()[0] or 0.0
227
228     def _sum_balance(self, accounts, date1, date2):
229         debit = self._sum_all(accounts, date1, date2, 'debit') or 0.0
230         credit = self._sum_all(accounts, date1, date2, 'credit') or 0.0
231         return (debit-credit)
232
233 #    def _sum_quantity(self, accounts, date1, date2):
234 #        ids = map(lambda x: x['id'], accounts)
235 #        if not len(ids):
236 #            return 0.0
237 #        account_analytic_obj = self.pool.get('account.analytic.account')
238 #        ids2 = account_analytic_obj.search(self.cr, self.uid,
239 #                [('parent_id', 'child_of', ids)])
240 #        self.cr.execute("SELECT sum(unit_amount) \
241 #                FROM account_analytic_line \
242 #                WHERE account_id IN ("+','.join(map(str, ids2))+") \
243 #                    AND date>=%s AND date<=%s",
244 #                (date1, date2))
245 #        return self.cr.fetchone()[0] or 0.0
246
247 report_sxw.report_sxw('report.account.analytic.account.balance',
248         'account.analytic.account', 'addons/account/project/report/analytic_balance.rml',
249         parser=account_analytic_balance, header=False)
250
251
252 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
253