[IMP] analytic_contract_hr_expense: replay of previous commit (removed during merge...
[odoo/odoo.git] / addons / account_analytic_analysis / account_analytic_analysis.py
index 5521315..0d51c95 100644 (file)
@@ -33,8 +33,7 @@ class account_analytic_account(osv.osv):
     def _analysis_all(self, cr, uid, ids, fields, arg, context=None):
         dp = 2
         res = dict([(i, {}) for i in ids])
-
-        parent_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context))
+        parent_ids = tuple(ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
         accounts = self.browse(cr, uid, ids, context=context)
 
         for f in fields:
@@ -60,7 +59,7 @@ class account_analytic_account(osv.osv):
                     res[id][f] = [int(id * 1000000 + int(x[0])) for x in result]
             elif f == 'last_worked_invoiced_date':
                 for id in ids:
-                    res[id][f] = 0.0
+                    res[id][f] = False
                 if parent_ids:
                     cr.execute("SELECT account_analytic_line.account_id, MAX(date) \
                             FROM account_analytic_line \
@@ -71,10 +70,6 @@ class account_analytic_account(osv.osv):
                         if account_id not in res:
                             res[account_id] = {}
                         res[account_id][f] = sum
-                for account in accounts:
-                    for child in account.child_ids:
-                        if res[account.id].get(f, '') < res.get(child.id, {}).get(f, ''):
-                            res[account.id][f] = res.get(child.id, {}).get(f, '')
             elif f == 'ca_to_invoice':
                 for id in ids:
                     res[id][f] = 0.0
@@ -103,26 +98,19 @@ class account_analytic_account(osv.osv):
                             WHERE account_analytic_account.id IN %s \
                                 AND account_analytic_line.invoice_id IS NULL \
                                 AND account_analytic_line.to_invoice IS NOT NULL \
-                                AND account_analytic_journal.type IN ('purchase','general') \
+                                AND account_analytic_journal.type IN ('purchase', 'general') \
                             GROUP BY account_analytic_account.id;""", (parent_ids,))
                     for account_id, sum in cr.fetchall():
                         if account_id not in res:
                             res[account_id] = {}
                         res[account_id][f] = round(sum, dp)
 
-                for account in accounts:
-                    #res.setdefault(account.id, 0.0)
-                    res2.setdefault(account.id, 0.0)
-                    for child in account.child_ids:
-                        if child.id != account.id:
-                            res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
-                            res2[account.id] += res2.get(child.id, 0.0)
                 # sum both result on account_id
                 for id in ids:
                     res[id][f] = round(res.get(id, {}).get(f, 0.0), dp) + round(res2.get(id, 0.0), 2)
             elif f == 'last_invoice_date':
                 for id in ids:
-                    res[id][f] = ''
+                    res[id][f] = False
                 if parent_ids:
                     cr.execute ("SELECT account_analytic_line.account_id, \
                                 DATE(MAX(account_invoice.date_invoice)) \
@@ -134,13 +122,9 @@ class account_analytic_account(osv.osv):
                             GROUP BY account_analytic_line.account_id",(parent_ids,))
                     for account_id, lid in cr.fetchall():
                         res[account_id][f] = lid
-                for account in accounts:
-                    for child in account.child_ids:
-                        if res[account.id][f] < res.get(child.id, {}).get(f, ''):
-                            res[account.id][f] = res.get(child.id, {}).get(f, '')
             elif f == 'last_worked_date':
                 for id in ids:
-                    res[id][f] = ''
+                    res[id][f] = False
                 if parent_ids:
                     cr.execute("SELECT account_analytic_line.account_id, MAX(date) \
                             FROM account_analytic_line \
@@ -151,10 +135,6 @@ class account_analytic_account(osv.osv):
                         if account_id not in res:
                             res[account_id] = {}
                         res[account_id][f] = lwd
-                for account in accounts:
-                    for child in account.child_ids:
-                        if res[account.id][f] < res.get(child.id, {}).get(f, ''):
-                            res[account.id][f] = res.get(child.id, {}).get(f, '')
             elif f == 'hours_qtt_non_invoiced':
                 for id in ids:
                     res[id][f] = 0.0
@@ -172,10 +152,6 @@ class account_analytic_account(osv.osv):
                         if account_id not in res:
                             res[account_id] = {}
                         res[account_id][f] = round(sua, dp)
-                for account in accounts:
-                    for child in account.child_ids:
-                        if account.id != child.id:
-                            res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
                 for id in ids:
                     res[id][f] = round(res[id][f], dp)
             elif f == 'hours_quantity':
@@ -194,19 +170,12 @@ class account_analytic_account(osv.osv):
                         if account_id not in res:
                             res[account_id] = {}
                         res[account_id][f] = round(hq, dp)
-                for account in accounts:
-                    for child in account.child_ids:
-                        if account.id != child.id:
-                            if account.id not in res:
-                                res[account.id] = {f: 0.0}
-                            res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
                 for id in ids:
                     res[id][f] = round(res[id][f], dp)
             elif f == 'ca_theorical':
                 # TODO Take care of pricelist and purchase !
                 for id in ids:
                     res[id][f] = 0.0
-                res2 = {}
                 # Warning
                 # This computation doesn't take care of pricelist !
                 # Just consider list_price
@@ -231,31 +200,15 @@ class account_analytic_account(osv.osv):
                             AND account_analytic_journal.type IN ('purchase', 'general')
                         GROUP BY account_analytic_line.account_id""",(parent_ids,))
                     for account_id, sum in cr.fetchall():
-                        res2[account_id] = round(sum, dp)
-
-                for account in accounts:
-                    res2.setdefault(account.id, 0.0)
-                    for child in account.child_ids:
-                        if account.id != child.id:
-                            if account.id not in res:
-                                res[account.id] = {f: 0.0}
-                            res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
-                            res[account.id][f] += res2.get(child.id, 0.0)
-
-                # sum both result on account_id
-                for id in ids:
-                    res[id][f] = round(res[id][f], dp) + round(res2.get(id, 0.0), dp)
-
+                        res[account_id][f] = round(sum, dp)
         return res
 
     def _ca_invoiced_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
         res_final = {}
-        child_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context))
+        child_ids = tuple(ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
         for i in child_ids:
-            res[i] =  {}
-            for n in [name]:
-                res[i][n] = 0.0
+            res[i] =  0.0
         if not child_ids:
             return res
 
@@ -268,24 +221,18 @@ class account_analytic_account(osv.osv):
                         AND account_analytic_journal.type = 'sale' \
                     GROUP BY account_analytic_line.account_id", (child_ids,))
             for account_id, sum in cr.fetchall():
-                res[account_id][name] = round(sum,2)
-        data = self._compute_level_tree(cr, uid, ids, child_ids, res, [name], context)
-        for i in data:
-            res_final[i] = data[i][name]
+                res[account_id] = round(sum,2)
+        res_final = res
         return res_final
 
     def _total_cost_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
         res_final = {}
-        child_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context))
-
+        child_ids = tuple(ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
         for i in child_ids:
-            res[i] =  {}
-            for n in [name]:
-                res[i][n] = 0.0
+            res[i] =  0.0
         if not child_ids:
             return res
-
         if child_ids:
             cr.execute("""SELECT account_analytic_line.account_id, COALESCE(SUM(amount), 0.0) \
                     FROM account_analytic_line \
@@ -295,17 +242,15 @@ class account_analytic_account(osv.osv):
                         AND amount<0 \
                     GROUP BY account_analytic_line.account_id""",(child_ids,))
             for account_id, sum in cr.fetchall():
-                res[account_id][name] = round(sum,2)
-        data = self._compute_level_tree(cr, uid, ids, child_ids, res, [name], context)
-        for i in data:
-            res_final[i] = data[i][name]
+                res[account_id] = round(sum,2)
+        res_final = res
         return res_final
 
     def _remaining_hours_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
         for account in self.browse(cr, uid, ids, context=context):
             if account.quantity_max != 0:
-                res[account.id] = account.quantity_max - account.hours_quantity
+                res[account.id] = account.quantity_max - account.hours_qtt_invoiced
             else:
                 res[account.id] = 0.0
         for id in ids:
@@ -324,7 +269,7 @@ class account_analytic_account(osv.osv):
 
     def _revenue_per_hour_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
-        for account in self.browse(cr, uid, ids):
+        for account in self.browse(cr, uid, ids, context=context):
             if account.hours_qtt_invoiced == 0:
                 res[account.id]=0.0
             else:
@@ -335,7 +280,7 @@ class account_analytic_account(osv.osv):
 
     def _real_margin_rate_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
-        for account in self.browse(cr, uid, ids):
+        for account in self.browse(cr, uid, ids, context=context):
             if account.ca_invoiced == 0:
                 res[account.id]=0.0
             elif account.total_cost != 0.0:
@@ -348,7 +293,7 @@ class account_analytic_account(osv.osv):
 
     def _remaining_ca_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
-        for account in self.browse(cr, uid, ids):
+        for account in self.browse(cr, uid, ids, context=context):
             if account.amount_max != 0:
                 res[account.id] = account.amount_max - account.ca_invoiced
             else:
@@ -359,7 +304,7 @@ class account_analytic_account(osv.osv):
 
     def _real_margin_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
-        for account in self.browse(cr, uid, ids):
+        for account in self.browse(cr, uid, ids, context=context):
             res[account.id] = account.ca_invoiced + account.total_cost
         for id in ids:
             res[id] = round(res.get(id, 0.0),2)
@@ -367,58 +312,145 @@ class account_analytic_account(osv.osv):
 
     def _theorical_margin_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
-        for account in self.browse(cr, uid, ids):
+        for account in self.browse(cr, uid, ids, context=context):
             res[account.id] = account.ca_theorical + account.total_cost
         for id in ids:
             res[id] = round(res.get(id, 0.0),2)
         return res
 
-    _columns ={
-        'ca_invoiced': fields.function(_ca_invoiced_calc, method=True, type='float', string='Invoiced Amount',
+    def _is_overdue_quantity(self, cr, uid, ids, fieldnames, args, context=None):
+        result = dict.fromkeys(ids, 0)
+        for record in self.browse(cr, uid, ids, context=context):
+            if record.quantity_max > 0.0:
+                result[record.id] = int(record.hours_quantity >= record.quantity_max)
+            else:
+                result[record.id] = 0
+        return result
+
+    def _get_analytic_account(self, cr, uid, ids, context=None):
+        result = set()
+        for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
+            result.add(line.account_id.id)
+        return list(result)
+
+    def _get_total_estimation(self, account):
+        tot_est = 0.0
+        if account.fix_price_invoices:
+            total_est += account.amount_max 
+        if account.invoice_on_timesheets:
+            tot_est += account.hours_qtt_est
+        return tot_est
+
+    def _get_total_invoiced(self, account):
+        total_invoiced = 0.0
+        if account.fix_price_invoices:
+            total_invoiced += account.ca_invoiced
+        if account.invoice_on_timesheets:
+            total_invoiced += account.hours_qtt_invoiced
+        return total_invoiced
+
+    def _get_total_remaining(self, account):
+        total_remaining = 0.0
+        if account.fix_price_invoices:
+            total_remaining += account.remaining_ca
+        if account.invoice_on_timesheets:
+            total_remaining += account.remaining_hours
+        return total_remaining
+
+    def _get_total_toinvoice(self, account):
+        total_toinvoice = 0.0
+        if account.fix_price_invoices:
+            total_toinvoice += account.ca_to_invoice
+        if account.invoice_on_timesheets:
+            total_toinvoice += account.hours_qtt_non_invoiced
+        return total_toinvoice
+
+    def _sum_of_fields(self, cr, uid, ids, name, arg, context=None):
+         res = dict([(i, {}) for i in ids])
+         for account in self.browse(cr, uid, ids, context=context):
+            res[account.id]['est_total'] = self._get_total_estimation(account)
+            res[account.id]['invoiced_total'] =  self._get_total_invoiced(account)
+            res[account.id]['remaining_total'] = self._get_total_remaining(account)
+            res[account.id]['toinvoice_total'] =  self._get_total_toinvoice(account)
+         return res
+
+    _columns = {
+        'is_overdue_quantity' : fields.function(_is_overdue_quantity, method=True, type='boolean', string='Overdue Quantity',
+                                                store={
+                                                    'account.analytic.line' : (_get_analytic_account, None, 20),
+                                                }),
+        'ca_invoiced': fields.function(_ca_invoiced_calc, type='float', string='Invoiced Amount',
             help="Total customer invoiced amount for this account.",
             digits_compute=dp.get_precision('Account')),
-        'total_cost': fields.function(_total_cost_calc, method=True, type='float', string='Total Costs',
+        'total_cost': fields.function(_total_cost_calc, type='float', string='Total Costs',
             help="Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets.",
             digits_compute=dp.get_precision('Account')),
-        'ca_to_invoice': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Amount',
+        'ca_to_invoice': fields.function(_analysis_all, multi='analytic_analysis', type='float', string='Uninvoiced Amount',
             help="If invoice from analytic account, the remaining amount you can invoice to the customer based on the total costs.",
             digits_compute=dp.get_precision('Account')),
-        'ca_theorical': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Theorical Revenue',
+        'ca_theorical': fields.function(_analysis_all, multi='analytic_analysis', type='float', string='Theoretical Revenue',
             help="Based on the costs you had on the project, what would have been the revenue if all these costs have been invoiced at the normal sale price provided by the pricelist.",
             digits_compute=dp.get_precision('Account')),
-        'hours_quantity': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Hours Tot',
-            help="Number of hours you spent on the analytic account (from timesheet). It computes on all journal of type 'general'."),
-        'last_invoice_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Last Invoice Date',
-            help="Date of the last invoice created for this analytic account."),
-        'last_worked_invoiced_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Invoiced Cost',
+        'hours_quantity': fields.function(_analysis_all, multi='analytic_analysis', type='float', string='Total Time',
+            help="Number of time you spent on the analytic account (from timesheet). It computes quantities on all journal of type 'general'."),
+        'last_invoice_date': fields.function(_analysis_all, multi='analytic_analysis', type='date', string='Last Invoice Date',
+            help="If invoice from the costs, this is the date of the latest invoiced."),
+        'last_worked_invoiced_date': fields.function(_analysis_all, multi='analytic_analysis', type='date', string='Date of Last Invoiced Cost',
             help="If invoice from the costs, this is the date of the latest work or cost that have been invoiced."),
-        'last_worked_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Cost/Work',
+        'last_worked_date': fields.function(_analysis_all, multi='analytic_analysis', type='date', string='Date of Last Cost/Work',
             help="Date of the latest work done on this account."),
-        'hours_qtt_non_invoiced': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Hours',
-            help="Number of hours (from journal of type 'general') that can be invoiced if you invoice based on analytic account."),
-        'hours_qtt_invoiced': fields.function(_hours_qtt_invoiced_calc, method=True, type='float', string='Invoiced Hours',
-            help="Number of hours that can be invoiced plus those that already have been invoiced."),
-        'remaining_hours': fields.function(_remaining_hours_calc, method=True, type='float', string='Remaining Hours',
-            help="Computed using the formula: Maximum Quantity - Hours Tot."),
-        'remaining_ca': fields.function(_remaining_ca_calc, method=True, type='float', string='Remaining Revenue',
+        'hours_qtt_non_invoiced': fields.function(_analysis_all, multi='analytic_analysis', type='float', string='Uninvoiced Time',
+            help="Number of time (hours/days) (from journal of type 'general') that can be invoiced if you invoice based on analytic account."),
+        'hours_qtt_invoiced': fields.function(_hours_qtt_invoiced_calc, type='float', string='Invoiced Time',
+            help="Number of time (hours/days) that can be invoiced plus those that already have been invoiced."),
+        'remaining_hours': fields.function(_remaining_hours_calc, type='float', string='Remaining Time',
+            help="Computed using the formula: Maximum Time - Total Time"),
+        'remaining_ca': fields.function(_remaining_ca_calc, type='float', string='Remaining Revenue',
             help="Computed using the formula: Max Invoice Price - Invoiced Amount.",
             digits_compute=dp.get_precision('Account')),
-        'revenue_per_hour': fields.function(_revenue_per_hour_calc, method=True, type='float', string='Revenue per Hours (real)',
-            help="Computed using the formula: Invoiced Amount / Hours Tot.",
+        'revenue_per_hour': fields.function(_revenue_per_hour_calc, type='float', string='Revenue per Time (real)',
+            help="Computed using the formula: Invoiced Amount / Total Time",
             digits_compute=dp.get_precision('Account')),
-        'real_margin': fields.function(_real_margin_calc, method=True, type='float', string='Real Margin',
+        'real_margin': fields.function(_real_margin_calc, type='float', string='Real Margin',
             help="Computed using the formula: Invoiced Amount - Total Costs.",
             digits_compute=dp.get_precision('Account')),
-        'theorical_margin': fields.function(_theorical_margin_calc, method=True, type='float', string='Theorical Margin',
+        'theorical_margin': fields.function(_theorical_margin_calc, type='float', string='Theoretical Margin',
             help="Computed using the formula: Theorial Revenue - Total Costs",
             digits_compute=dp.get_precision('Account')),
-        'real_margin_rate': fields.function(_real_margin_rate_calc, method=True, type='float', string='Real Margin Rate (%)',
+        'real_margin_rate': fields.function(_real_margin_rate_calc, type='float', string='Real Margin Rate (%)',
             help="Computes using the formula: (Real Margin / Total Costs) * 100.",
             digits_compute=dp.get_precision('Account')),
-        'month_ids': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'),
-        'user_ids': fields.function(_analysis_all, method=True, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'),
+        'fix_price_invoices' : fields.boolean('Fix Price Invoices'),
+        'invoice_on_timesheets' : fields.boolean("Invoice On Timesheets"),
+        'month_ids': fields.function(_analysis_all, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'),
+        'user_ids': fields.function(_analysis_all, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'),
+        'template_id':fields.many2one('account.analytic.account', 'Template of Contract'),
+        'hours_qtt_est': fields.float('Estimation of Hours to Invoice'),
+        'est_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all"),
+        'invoiced_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all"),
+        'remaining_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all"),
+        'toinvoice_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all"),
     }
 
+    def on_change_template(self, cr, uid, id, template_id, context=None):
+        if not template_id:
+            return {}
+        res = {'value':{}}
+        template = self.browse(cr, uid, template_id, context=context)
+        if template.date_start:
+            res['value']['date_start'] = str(template.date_start)
+        if template.date:
+            res['value']['date'] = str(template.date)
+        res['value']['fix_price_invoices'] = template.fix_price_invoices
+        res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets
+        res['value']['quantity_max'] = template.quantity_max
+        res['value']['remaining_hours'] = template.remaining_hours
+        res['value']['amount_max'] = template.amount_max
+        res['value']['to_invoice'] = template.to_invoice.id
+        res['value']['pricelist_id'] = template.pricelist_id.id
+        res['value']['description'] = template.description
+        return res
+
 account_analytic_account()
 
 class account_analytic_account_summary_user(osv.osv):
@@ -435,7 +467,7 @@ class account_analytic_account_summary_user(osv.osv):
         max_user = cr.fetchone()[0]
         account_ids = [int(str(x/max_user - (x%max_user == 0 and 1 or 0))) for x in ids]
         user_ids = [int(str(x-((x/max_user - (x%max_user == 0 and 1 or 0)) *max_user))) for x in ids]
-        parent_ids = tuple(account_obj.search(cr, uid, [('parent_id', 'child_of', account_ids)], context=context))
+        parent_ids = tuple(account_ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
         if parent_ids:
             cr.execute('SELECT id, unit_amount ' \
                     'FROM account_analytic_analysis_summary_user ' \
@@ -443,20 +475,13 @@ class account_analytic_account_summary_user(osv.osv):
                         'AND "user" IN %s',(parent_ids, tuple(user_ids),))
             for sum_id, unit_amount in cr.fetchall():
                 res[sum_id] = unit_amount
-        for obj_id in ids:
-            res.setdefault(obj_id, 0.0)
-            for child_id in account_obj.search(cr, uid,
-                    [('parent_id', 'child_of', [int(str(obj_id/max_user - (obj_id%max_user == 0 and 1 or 0)))])]):
-                if child_id != int(str(obj_id/max_user - (obj_id%max_user == 0 and 1 or 0))):
-                    res[obj_id] += res.get((child_id * max_user) + obj_id -((obj_id/max_user - (obj_id%max_user == 0 and 1 or 0)) * max_user), 0.0)
         for id in ids:
             res[id] = round(res.get(id, 0.0), 2)
         return res
 
     _columns = {
         'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
-        'unit_amount': fields.function(_unit_amount, method=True, type='float',
-            string='Total Time'),
+        'unit_amount': fields.float('Total Time'),
         'user': fields.many2one('res.users', 'User'),
     }
 
@@ -496,96 +521,6 @@ class account_analytic_account_summary_user(osv.osv):
                 'GROUP BY u."user", u.account_id, u.max_user' \
                 ')')
 
-    def _read_flat(self, cr, user, ids, fields, context=None, load='_classic_read'):
-        if not context:
-            context = {}
-        if not ids:
-            return []
-
-        if fields is None:
-            fields = self._columns.keys()
-        res_trans_obj = self.pool.get('ir.translation')
-
-        # construct a clause for the rules:
-        d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, 'read', context=context)
-
-        # all inherited fields + all non inherited fields for which the attribute whose name is in load is True
-        fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x],'_classic_write'), fields) + self._inherits.values()
-        res = []
-        cr.execute('SELECT MAX(id) FROM res_users')
-        max_user = cr.fetchone()[0]
-        if fields_pre:
-            fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre)
-            for i in range(0, len(ids), cr.IN_MAX):
-                sub_ids = ids[i:i+cr.IN_MAX]
-                if d1:
-                    cr.execute('SELECT %s FROM \"%s\" WHERE id IN (%s) ' \
-                            'AND account_id IN (%s) ' \
-                            'AND "user" IN (%s) AND %s ORDER BY %s' % \
-                            (','.join(fields_pre2 + ['id']), self._table,
-                                ','.join([str(x) for x in sub_ids]),
-                                ','.join([str(x/max_user - (x%max_user == 0 and 1 or 0)) for x in sub_ids]),
-                                ','.join([str(x-((x/max_user - (x%max_user == 0 and 1 or 0)) *max_user)) for x in sub_ids]), d1,
-                                self._order),d2)
-                    if not cr.rowcount == len({}.fromkeys(sub_ids)):
-                        raise except_orm(_('AccessError'),
-                                _('You try to bypass an access rule (Document type: %s).') % self._description)
-                else:
-                    cr.execute('SELECT %s FROM \"%s\" WHERE id IN (%s) ' \
-                            'AND account_id IN (%s) ' \
-                            'AND "user" IN (%s) ORDER BY %s' % \
-                            (','.join(fields_pre2 + ['id']), self._table,
-                                ','.join([str(x) for x in sub_ids]),
-                                ','.join([str(x/max_user - (x%max_user == 0 and 1 or 0)) for x in sub_ids]),
-                                ','.join([str(x-((x/max_user - (x%max_user == 0 and 1 or 0)) *max_user)) for x in sub_ids]),
-                                self._order))
-                res.extend(cr.dictfetchall())
-        else:
-            res = map(lambda x: {'id': x}, ids)
-        for f in fields_pre:
-            if self._columns[f].translate:
-                ids = map(lambda x: x['id'], res)
-                res_trans = res_trans_obj._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids)
-                for r in res:
-                    r[f] = res_trans.get(r['id'], False) or r[f]
-
-        for table in self._inherits:
-            col = self._inherits[table]
-            cols = intersect(self._inherit_fields.keys(), fields)
-            if not cols:
-                continue
-            res2 = self.pool.get(table).read(cr, user, [x[col] for x in res], cols, context, load)
-
-            res3 = {}
-            for r in res2:
-                res3[r['id']] = r
-                del r['id']
-
-            for record in res:
-                record.update(res3[record[col]])
-                if col not in fields:
-                    del record[col]
-
-        # all fields which need to be post-processed by a simple function (symbol_get)
-        fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields)
-        if fields_post:
-            # maybe it would be faster to iterate on the fields then on res, so that we wouldn't need
-            # to get the _symbol_get in each occurence
-            for r in res:
-                for f in fields_post:
-                    r[f] = self.columns[f]._symbol_get(r[f])
-        ids = map(lambda x: x['id'], res)
-
-        # all non inherited fields for which the attribute whose name is in load is False
-        fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields)
-        for f in fields_post:
-            # get the value of that field for all records/ids
-            res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
-            for record in res:
-                record[f] = res2[record['id']]
-
-        return res
-
 account_analytic_account_summary_user()
 
 class account_analytic_account_summary_month(osv.osv):
@@ -594,32 +529,9 @@ class account_analytic_account_summary_month(osv.osv):
     _auto = False
     _rec_name = 'month'
 
-    def _unit_amount(self, cr, uid, ids, name, arg, context=None):
-        res = {}
-        account_obj = self.pool.get('account.analytic.account')
-        account_ids = [int(str(int(x))[:-6]) for x in ids]
-        month_ids = [int(str(int(x))[-6:]) for x in ids]
-        parent_ids = tuple(account_obj.search(cr, uid, [('parent_id', 'child_of', account_ids)], context=context))
-        if parent_ids:
-            cr.execute('SELECT id, unit_amount ' \
-                    'FROM account_analytic_analysis_summary_month ' \
-                    'WHERE account_id IN %s ' \
-                        'AND month_id IN %s ',(parent_ids, tuple(month_ids),))
-            for sum_id, unit_amount in cr.fetchall():
-                res[sum_id] = unit_amount
-        for obj_id in ids:
-            res.setdefault(obj_id, 0.0)
-            for child_id in account_obj.search(cr, uid,
-                    [('parent_id', 'child_of', [int(str(int(obj_id))[:-6])])]):
-                if child_id != int(str(int(obj_id))[:-6]):
-                    res[obj_id] += res.get(int(child_id * 1000000 + int(str(int(obj_id))[-6:])), 0.0)
-        for id in ids:
-            res[id] = round(res.get(id, 0.0), 2)
-        return res
-
     _columns = {
         'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
-        'unit_amount': fields.function(_unit_amount, method=True, type='float', string='Total Time'),
+        'unit_amount': fields.float('Total Time'),
         'month': fields.char('Month', size=32, readonly=True),
     }
 
@@ -627,7 +539,7 @@ class account_analytic_account_summary_month(osv.osv):
         tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_month')
         cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \
                 'SELECT ' \
-                    '(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id  * 1000000))::integer AS id, ' \
+                    '(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id  * 1000000::bigint))::bigint AS id, ' \
                     'd.account_id AS account_id, ' \
                     'TO_CHAR(d.month, \'Mon YYYY\') AS month, ' \
                     'TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') AS month_id, ' \
@@ -670,93 +582,6 @@ class account_analytic_account_summary_month(osv.osv):
                 'GROUP BY d.month, d.account_id ' \
                 ')')
 
-    def _read_flat(self, cr, user, ids, fields, context=None, load='_classic_read'):
-        if not context:
-            context = {}
-        if not ids:
-            return []
-
-        if fields is None:
-            fields = self._columns.keys()
-        res_trans_obj = self.pool.get('ir.translation')
-        # construct a clause for the rules:
-        d1, d2, tables= self.pool.get('ir.rule').domain_get(cr, user, self._name)
-
-        # all inherited fields + all non inherited fields for which the attribute whose name is in load is True
-        fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x],'_classic_write'), fields) + self._inherits.values()
-        res = []
-        if fields_pre:
-            fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre)
-            for i in range(0, len(ids), cr.IN_MAX):
-                sub_ids = ids[i:i+cr.IN_MAX]
-                if d1:
-                    cr.execute('SELECT %s FROM \"%s\" WHERE id IN (%s) ' \
-                            'AND account_id IN (%s) ' \
-                            'AND month_id IN (%s) AND %s ORDER BY %s' % \
-                            (','.join(fields_pre2 + ['id']), self._table,
-                                ','.join([str(x) for x in sub_ids]),
-                                ','.join([str(x)[:-6] for x in sub_ids]),
-                                ','.join([str(x)[-6:] for x in sub_ids]), d1,
-                                self._order),d2)
-                    if not cr.rowcount == len({}.fromkeys(sub_ids)):
-                        raise except_orm(_('AccessError'),
-                                _('You try to bypass an access rule (Document type: %s).') % self._description)
-                else:
-                    cr.execute('SELECT %s FROM \"%s\" WHERE id IN (%s) ' \
-                            'AND account_id IN (%s) ' \
-                            'AND month_id IN (%s) ORDER BY %s' % \
-                            (','.join(fields_pre2 + ['id']), self._table,
-                                ','.join([str(x) for x in sub_ids]),
-                                ','.join([str(x)[:-6] for x in sub_ids]),
-                                ','.join([str(x)[-6:] for x in sub_ids]),
-                                self._order))
-                res.extend(cr.dictfetchall())
-        else:
-            res = map(lambda x: {'id': x}, ids)
-
-        for f in fields_pre:
-            if self._columns[f].translate:
-                ids = map(lambda x: x['id'], res)
-                res_trans = res_trans_obj._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids)
-                for r in res:
-                    r[f] = res_trans.get(r['id'], False) or r[f]
-
-        for table in self._inherits:
-            col = self._inherits[table]
-            cols = intersect(self._inherit_fields.keys(), fields)
-            if not cols:
-                continue
-            res2 = self.pool.get(table).read(cr, user, [x[col] for x in res], cols, context, load)
-
-            res3 = {}
-            for r in res2:
-                res3[r['id']] = r
-                del r['id']
-
-            for record in res:
-                record.update(res3[record[col]])
-                if col not in fields:
-                    del record[col]
-
-        # all fields which need to be post-processed by a simple function (symbol_get)
-        fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields)
-        if fields_post:
-            # maybe it would be faster to iterate on the fields then on res, so that we wouldn't need
-            # to get the _symbol_get in each occurence
-            for r in res:
-                for f in fields_post:
-                    r[f] = self.columns[f]._symbol_get(r[f])
-        ids = map(lambda x: x['id'], res)
-
-        # all non inherited fields for which the attribute whose name is in load is False
-        fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields)
-        for f in fields_post:
-            # get the value of that field for all records/ids
-            res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
-            for record in res:
-                record[f] = res2[record['id']]
-        return res
 
 account_analytic_account_summary_month()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: