Odoo18-Base/addons/sale_timesheet/models/project_update.py
2025-01-06 10:57:38 +07:00

63 lines
3.7 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
from odoo.tools import float_utils, formatLang
from odoo.tools.misc import format_duration
class ProjectUpdate(models.Model):
_inherit = 'project.update'
@api.model
def _get_template_values(self, project):
template_values = super(ProjectUpdate, self)._get_template_values(project)
profitability_values = self._get_profitability_values(project)
show_profitability = bool(profitability_values and profitability_values.get('account_id') and (profitability_values.get('costs') or profitability_values.get('revenues')))
return {
**template_values,
'show_profitability': show_profitability,
'show_activities': template_values['show_activities'] or show_profitability,
'profitability': profitability_values,
'format_value': lambda value, is_hour: str(round(value, 2)) if not is_hour else format_duration(value),
}
@api.model
def _get_profitability_values(self, project):
costs_revenues = project.account_id and project.allow_billable
if not (self.env.user.has_group('project.group_project_manager') and costs_revenues):
return {}
profitability_items = project._get_profitability_items(False)
if project._get_profitability_sequence_per_invoice_type() and profitability_items and 'revenues' in profitability_items and 'costs' in profitability_items: # sort the data values
profitability_items['revenues']['data'] = sorted(profitability_items['revenues']['data'], key=lambda k: k['sequence'])
profitability_items['costs']['data'] = sorted(profitability_items['costs']['data'], key=lambda k: k['sequence'])
costs = sum(profitability_items['costs']['total'].values())
revenues = sum(profitability_items['revenues']['total'].values())
margin = revenues + costs
to_bill_to_invoice = profitability_items['costs']['total']['to_bill'] + profitability_items['revenues']['total']['to_invoice']
billed_invoiced = profitability_items['costs']['total']['billed'] + profitability_items['revenues']['total']['invoiced']
expected_percentage, to_bill_to_invoice_percentage, billed_invoiced_percentage = 0, 0, 0
if revenues:
expected_percentage = formatLang(self.env, (margin / revenues) * 100, digits=0)
if profitability_items['revenues']['total']['to_invoice']:
to_bill_to_invoice_percentage = formatLang(self.env, (to_bill_to_invoice / profitability_items['revenues']['total']['to_invoice']) * 100, digits=0)
if profitability_items['revenues']['total']['invoiced']:
billed_invoiced_percentage = formatLang(self.env, (billed_invoiced / profitability_items['revenues']['total']['invoiced']) * 100, digits=0)
return {
'account_id': project.account_id,
'costs': profitability_items['costs'],
'revenues': profitability_items['revenues'],
'expected_percentage': expected_percentage,
'to_bill_to_invoice_percentage': to_bill_to_invoice_percentage,
'billed_invoiced_percentage': billed_invoiced_percentage,
'total': {
'costs': costs,
'revenues': revenues,
'margin': margin,
'margin_percentage': formatLang(self.env,
not float_utils.float_is_zero(costs, precision_digits=2) and (margin / -costs) * 100 or 0.0,
digits=0),
},
'labels': project._get_profitability_labels(),
}