- _columns ={
- 'ca_invoiced': fields.function(_ca_invoiced_calc, method=True, type='float', string='Invoiced Amount', help="Total customer invoiced amount for this account."),
- 'total_cost': fields.function(_total_cost_calc, method=True, 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."),
- 'ca_to_invoice': fields.function(_analysis_all, method=True, 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."),
- 'ca_theorical': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Theorical 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."),
- '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', 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', 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', help="Computed using the formula: Max Invoice Price - Invoiced Amount."),
- '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."),
- 'real_margin': fields.function(_real_margin_calc, method=True, type='float', string='Real Margin', help="Computed using the formula: Invoiced Amount - Total Costs."),
- 'theorical_margin': fields.function(_theorical_margin_calc, method=True, type='float', string='Theorical Margin', help="Computed using the formula: Theorial Revenue - Total Costs"),
- 'real_margin_rate': fields.function(_real_margin_rate_calc, method=True, type='float', string='Real Margin Rate (%)', help="Computes using the formula: (Real Margin / Total Costs) * 100."),
- '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'),
+ 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:
+ 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])
+ 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, 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, 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, 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 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."),
+ '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, 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, 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 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')),
+ '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, 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, 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, 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"),