[MIG] init 18.0

This commit is contained in:
Stéphan Sainléger
2026-01-20 15:24:30 +01:00
parent 763fca0d30
commit 27c7904e28
122 changed files with 0 additions and 4415 deletions

View File

@@ -1 +0,0 @@
from . import billable_time, account_analytic_line

View File

@@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
from odoo.osv import expression
class AccountAnalyticLine(models.Model):
_inherit = 'account.analytic.line'
def _timesheet_get_portal_domain(self):
domain = super()._timesheet_get_portal_domain()
return expression.AND([domain, [('exclude_from_sale_order', '=', False)]])

View File

@@ -1,124 +0,0 @@
from odoo import models, fields, api, _
from odoo.tools.float_utils import float_compare
class Task(models.Model):
_inherit = "project.task"
billable_effective_hours = fields.Float(
compute="_compute_billable_effective_hours",
string="Billable Effective Hours",
store=True,
)
non_billable_effective_hours = fields.Float(
compute="_compute_non_billable_effective_hours",
string="Non Billable Effective Hours",
store=True,
)
billable_remaining_hours = fields.Float(
compute="_compute_billable_remaining_hours",
string="Billable Remaining Hours",
store=True,
help="Total Billable remaining time (without exclude_from_sale_order timesheet lines), can be re-estimated periodically by the assignee of the task."
)
billable_progress = fields.Float(
compute="_compute_billable_progress_hours",
string="Billable Progress",
store=True,
group_operator="avg",
)
subtask_billable_effective_hours = fields.Float(
compute="_compute_subtask_billable_effective_hours",
string="Subtask Billable Effective Hours",
store=True,
recursive=True,
)
subtask_non_billable_effective_hours = fields.Float(
compute="_compute_subtask_non_billable_effective_hours",
string="Subtask Non Billable Effective Hours",
store=True,
recursive=True,
)
total_billable_hours_spent = fields.Float(
"Total Billable Hours",
compute="_compute_total_billable_hours_spent",
store=True,
help="Billable time spent on this task and its sub-tasks (and their own sub-tasks).",
)
total_non_billable_hours_spent = fields.Float(
"Total Non Billable Hours",
compute="_compute_total_non_billable_hours_spent",
store=True,
help="Non billable time spent on this task and its sub-tasks (and their own sub-tasks).",
)
@api.depends('timesheet_ids.unit_amount', 'timesheet_ids.exclude_from_sale_order')
def _compute_billable_effective_hours(self):
if not any(self._ids):
for task in self:
filtered_timesheets = task.timesheet_ids.filtered(lambda t: not t.exclude_from_sale_order)
task.billable_effective_hours = sum(filtered_timesheets.mapped('unit_amount'))
return
timesheet_read_group = self.env['account.analytic.line'].read_group(
[('task_id', 'in', self.ids), ('exclude_from_sale_order', '=', False)], # We exclude the lines (timesheet) which are excluded from billing
['unit_amount', 'task_id'],
['task_id']
)
timesheets_per_task = {res['task_id'][0]: res['unit_amount'] for res in timesheet_read_group}
for task in self:
task.billable_effective_hours = timesheets_per_task.get(task.id, 0.0)
@api.depends('effective_hours','billable_effective_hours')
def _compute_non_billable_effective_hours(self):
for task in self:
task.non_billable_effective_hours = task.effective_hours - task.billable_effective_hours
@api.depends('billable_effective_hours', 'subtask_billable_effective_hours', 'planned_hours')
def _compute_billable_remaining_hours(self):
for task in self:
task.billable_remaining_hours = task.planned_hours - task.billable_effective_hours - task.subtask_billable_effective_hours
@api.depends('child_ids.billable_effective_hours', 'child_ids.subtask_billable_effective_hours')
def _compute_subtask_billable_effective_hours(self):
for task in self:
task.subtask_billable_effective_hours = sum(child_task.billable_effective_hours + child_task.subtask_billable_effective_hours for child_task in task.child_ids)
@api.depends('child_ids.non_billable_effective_hours', 'child_ids.subtask_non_billable_effective_hours')
def _compute_subtask_non_billable_effective_hours(self):
for task in self:
task.subtask_non_billable_effective_hours = sum(child_task.non_billable_effective_hours + child_task.subtask_non_billable_effective_hours for child_task in task.child_ids)
@api.depends('billable_effective_hours', 'subtask_billable_effective_hours', 'planned_hours')
def _compute_billable_progress_hours(self):
for task in self:
if (task.planned_hours > 0.0):
task_total_hours = task.billable_effective_hours + task.subtask_billable_effective_hours
if float_compare(task_total_hours, task.planned_hours, precision_digits=2) >= 0:
task.billable_progress = 100
else:
task.billable_progress = round(100.0 * task_total_hours / task.planned_hours, 2)
else:
task.billable_progress = 0.0
@api.depends('billable_effective_hours', 'subtask_billable_effective_hours')
def _compute_total_billable_hours_spent(self):
for task in self:
task.total_billable_hours_spent = (
task.billable_effective_hours + task.subtask_billable_effective_hours
)
@api.depends("non_billable_effective_hours", "subtask_non_billable_effective_hours")
def _compute_total_non_billable_hours_spent(self):
for task in self:
task.total_non_billable_hours_spent = (
task.non_billable_effective_hours + task.subtask_non_billable_effective_hours
)