[MIG] project_working_time_task_portal: migrate to 18.0
This commit is contained in:
2
project_working_time_task_portal/models/__init__.py
Normal file
2
project_working_time_task_portal/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import project_task
|
||||
from . import account_analytic_line
|
||||
@@ -0,0 +1,12 @@
|
||||
# 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)]])
|
||||
172
project_working_time_task_portal/models/project_task.py
Normal file
172
project_working_time_task_portal/models/project_task.py
Normal file
@@ -0,0 +1,172 @@
|
||||
from odoo import api, fields, models
|
||||
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
|
||||
["task_id"],
|
||||
["unit_amount:sum"],
|
||||
)
|
||||
|
||||
timesheets_per_task = {
|
||||
task.id: unit_amount for task, unit_amount 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",
|
||||
"allocated_hours",
|
||||
)
|
||||
def _compute_billable_remaining_hours(self):
|
||||
for task in self:
|
||||
task.billable_remaining_hours = (
|
||||
task.allocated_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",
|
||||
"allocated_hours",
|
||||
)
|
||||
def _compute_billable_progress_hours(self):
|
||||
for task in self:
|
||||
if task.allocated_hours > 0.0:
|
||||
task_total_hours = (
|
||||
task.billable_effective_hours
|
||||
+ task.subtask_billable_effective_hours
|
||||
)
|
||||
if (
|
||||
float_compare(
|
||||
task_total_hours, task.allocated_hours, precision_digits=2
|
||||
)
|
||||
>= 0
|
||||
):
|
||||
task.billable_progress = 100
|
||||
else:
|
||||
task.billable_progress = round(
|
||||
100.0 * task_total_hours / task.allocated_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
|
||||
)
|
||||
Reference in New Issue
Block a user