[IMP] account_analytic_analysis, analytic_contract_hr_expense: remaining to invoice...
[odoo/odoo.git] / addons / account_analytic_analysis / account_analytic_analysis.py
index 0a517fa..12e9e29 100644 (file)
@@ -224,45 +224,7 @@ class account_analytic_account(osv.osv):
                 res[account_id] = round(sum,2)
         res_final = res
         return res_final
-    
-    def _expense_invoiced_calc(self, cr, uid, ids, name, arg, context=None):
-        res = {}
-        res_final = {}
-        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] =  0.0
-        if not child_ids:
-            return res
-
-        if child_ids:
-            cr.execute("select hel.analytic_account,SUM(hel.unit_amount*hel.unit_quantity) from hr_expense_line as hel\
-                        LEFT JOIN hr_expense_expense as he ON he.id = hel.expense_id\
-                        where he.state = 'paid' and hel.analytic_account IN %s \
-                        GROUP BY hel.analytic_account",(child_ids,))
-            for account_id, sum in cr.fetchall():
-                res[account_id] = sum
-        res_final = res
-        return res_final
-    
-    def _expense_to_invoice_calc(self, cr, uid, ids, name, arg, context=None):
-        res = {}
-        res_final = {}
-        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] =  0.0
-        if not child_ids:
-            return res
 
-        if child_ids:
-            cr.execute("select hel.analytic_account, SUM(hel.unit_amount*hel.unit_quantity) from hr_expense_line as hel\
-                        LEFT JOIN hr_expense_expense as he ON he.id = hel.expense_id\
-                        where he.state = 'invoiced' and hel.analytic_account IN %s \
-                        GROUP BY hel.analytic_account",(child_ids,))
-            for account_id, sum in cr.fetchall():
-                res[account_id] = sum
-        res_final = res
-        return res_final
-    
     def _total_cost_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
         res_final = {}
@@ -288,13 +250,19 @@ class account_analytic_account(osv.osv):
         res = {}
         for account in self.browse(cr, uid, ids, context=context):
             if account.quantity_max != 0:
-                res[account.id] = account.quantity_max - account.hours_qtt_invoiced
+                res[account.id] = account.quantity_max - account.hours_quantity
             else:
                 res[account.id] = 0.0
         for id in ids:
             res[id] = round(res.get(id, 0.0),2)
         return res
 
+    def _remaining_hours_to_invoice_calc(self, cr, uid, ids, name, arg, context=None):
+        res = {}
+        for account in self.browse(cr, uid, ids, context=context):
+            res[account.id] = max(account.hours_qtt_est - account.hours_qtt_invoiced, account.hours_qtt_non_invoiced)
+        return res
+
     def _hours_qtt_invoiced_calc(self, cr, uid, ids, name, arg, context=None):
         res = {}
         for account in self.browse(cr, uid, ids, context=context):
@@ -333,22 +301,9 @@ class account_analytic_account(osv.osv):
         res = {}
         for account in self.browse(cr, uid, ids, context=context):
             if account.amount_max != 0:
-                res[account.id] = account.amount_max - account.ca_invoiced
+                res[account.id] = max(account.amount_max - account.ca_invoiced, account.ca_to_invoice)
             else:
                 res[account.id]=0.0
-        for id in ids:
-            res[id] = round(res.get(id, 0.0),2)
-        return res
-    
-    def _remaining_expnse_calc(self, cr, uid, ids, name, arg, context=None):
-        res = {}
-        for account in self.browse(cr, uid, ids, context=context):
-            if account.expense_max != 0:
-                res[account.id] = account.expense_max - account.expense_invoiced
-            else:
-                res[account.id]=0.0
-        for id in ids:
-            res[id] = round(res.get(id, 0.0),2)
         return res
 
     def _real_margin_calc(self, cr, uid, ids, name, arg, context=None):
@@ -381,33 +336,46 @@ class account_analytic_account(osv.osv):
         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:
+            tot_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_to_invoice
+        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])
-         total_max = 0.0
-         total_invoiced = 0.0
-         total_toinvoice = 0.0
-         total_remaining = 0.0
          for account in self.browse(cr, uid, ids, context=context):
-            if account.fix_price_invoices:
-                total_max += account.amount_max 
-                total_invoiced += account.ca_invoiced
-                total_remaining += account.remaining_ca
-                total_toinvoice += account.ca_to_invoice
-            if account.invoice_on_timesheets:
-                total_max += account.quantity_max 
-                total_invoiced += account.hours_qtt_invoiced
-                total_remaining += account.remaining_hours
-                total_toinvoice += account.hours_qtt_non_invoiced
-            if account.charge_expenses:
-                total_max += account.expense_max 
-                total_invoiced += account.expense_invoiced
-                total_remaining += account.remaining_expense
-                total_toinvoice += account.expense_to_invoice
-            res[account.id]['est_total'] = total_max or 0.0
-            res[account.id]['invoiced_total'] =  total_invoiced or 0.0
-            res[account.id]['remaining_total'] = total_remaining or 0.0
-            res[account.id]['toinvoice_total'] =  total_toinvoice or 0.0
+            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 = {
@@ -427,7 +395,7 @@ class account_analytic_account(osv.osv):
         '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, multi='analytic_analysis', type='float', string='Total Time',
+        'hours_quantity': fields.function(_analysis_all, multi='analytic_analysis', type='float', string='Total Worked 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."),
@@ -440,7 +408,9 @@ class account_analytic_account(osv.osv):
         '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"),
+            help="Computed using the formula: Maximum Time - Total Worked Time"),
+        'remaining_hours_to_invoice': fields.function(_remaining_hours_to_invoice_calc, type='float', string='Remaining Time',
+            help="Computed using the formula: Maximum Time - Total Invoiced 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')),
@@ -458,69 +428,33 @@ class account_analytic_account(osv.osv):
             digits_compute=dp.get_precision('Account')),
         'fix_price_invoices' : fields.boolean('Fix Price Invoices'),
         'invoice_on_timesheets' : fields.boolean("Invoice On Timesheets"),
-        'charge_expenses' : fields.boolean('Charge Expenses'),
         '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'),
-        'expense_invoiced' : fields.function(_expense_invoiced_calc, type="float"),
-        'expense_to_invoice' : fields.function(_expense_to_invoice_calc, type='float'),
-        'remaining_expense' : fields.function(_remaining_expnse_calc, type="float"), 
-        #'fix_exp_max' : fields.float('Max. amt'),
-        #'timesheet_max': fields.float('max_timesheet'),
-        'expense_max': fields.float('expenses'),
+        '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):
+
+    def on_change_template(self, cr, uid, ids, template_id, context=None):
         if not template_id:
             return {}
         res = {'value':{}}
-        template = self.browse(cr, uid, template_id)
+        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
-    
-    def open_hr_expense(self, cr, uid, ids, context=None):
-        account = self.browse(cr, uid, ids[0], context)
-        data_obj = self.pool.get('ir.model.data')
-        try:
-            journal_id = data_obj.get_object(cr, uid, 'hr_timesheet', 'analytic_journal').id
-        except ValueError:
-            journal_id = False
-        line_ids = self.pool.get('hr.expense.line').search(cr,uid,[('analytic_account','=',account.id)])
-        id2 = data_obj._get_id(cr, uid, 'hr_expense', 'view_expenses_form')
-        id3 = data_obj._get_id(cr, uid, 'hr_expense', 'view_expenses_tree')
-        if id2:
-            id2 = data_obj.browse(cr, uid, id2, context=context).res_id
-        if id3:
-            id3 = data_obj.browse(cr, uid, id3, context=context).res_id
-        domain = [('line_ids','in',line_ids)]
-        return {
-            'type': 'ir.actions.act_window',
-            'name': _('Expenses'),
-            'view_type': 'form',
-            'view_mode': 'tree,form',
-            'views': [(id3,'tree'),(id2,'form')],
-            'domain' : domain,
-            'res_model': 'hr.expense.expense',
-            'nodestroy': True,
-        }
-    
-    def hr_to_invoiced_expense(self, cr, uid, ids, context=None):
-         res = self.open_hr_expense(cr,uid,ids,context)
-         account = self.browse(cr, uid, ids[0], context)
-         line_ids = self.pool.get('hr.expense.line').search(cr,uid,[('analytic_account','=',account.id)])
-         res['domain'] = [('line_ids','in',line_ids),('state','=','invoiced')]
-         return res
 
 account_analytic_account()