[ADD] analytic_contract_hr_expense: split of features of account_analytic_analysis...
[odoo/odoo.git] / addons / account_analytic_analysis / account_analytic_analysis.py
index d379ba2..76aba53 100644 (file)
@@ -98,7 +98,7 @@ 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:
@@ -250,7 +250,7 @@ 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_quantity
+                res[account.id] = account.quantity_max - account.hours_qtt_invoiced
             else:
                 res[account.id] = 0.0
         for id in ids:
@@ -322,7 +322,7 @@ class account_analytic_account(osv.osv):
         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.quantity >= record.quantity_max)
+                result[record.id] = int(record.hours_quantity >= record.quantity_max)
             else:
                 result[record.id] = 0
         return result
@@ -333,6 +333,47 @@ class account_analytic_account(osv.osv):
             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={
@@ -379,10 +420,39 @@ class account_analytic_account(osv.osv):
         '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')),
+        '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):
+        if not template_id:
+            return {}
+        res = {'value':{}}
+        template = self.browse(cr, uid, template_id)
+        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']['charge_expenses'] = template.charge_expenses
+        res['value']['quantity_max'] = template.quantity_max
+        res['value']['remaining_hours'] = template.remaining_hours
+        res['value']['amount_max'] = template.amount_max
+        res['value']['expense_max'] = template.expense_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):
@@ -413,8 +483,7 @@ class account_analytic_account_summary_user(osv.osv):
 
     _columns = {
         'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
-        'unit_amount': fields.function(_unit_amount, type='float',
-            string='Total Time'),
+        'unit_amount': fields.float('Total Time'),
         'user': fields.many2one('res.users', 'User'),
     }
 
@@ -454,96 +523,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 context is None:
-            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):
@@ -552,26 +531,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(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_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 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, type='float', string='Total Time'),
+        'unit_amount': fields.float('Total Time'),
         'month': fields.char('Month', size=32, readonly=True),
     }
 
@@ -622,92 +584,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 context is None:
-            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: