[IMP] project_working_time_task: display total billable and non billable hours on task #30

Merged
mondot merged 1 commits from project_working_time_task-total-billable-hours into 16.0 2025-11-19 09:39:53 +00:00
3 changed files with 89 additions and 2 deletions

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 16.0\n" "Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-18 14:17+0000\n" "POT-Creation-Date: 2025-11-18 16:44+0000\n"
"PO-Revision-Date: 2025-11-18 14:17+0000\n" "PO-Revision-Date: 2025-11-18 16:44+0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -67,6 +67,15 @@ msgstr "Jours restants facturables"
msgid "Billable Remaining Hours" msgid "Billable Remaining Hours"
msgstr "Heures restantes facturables" msgstr "Heures restantes facturables"
#. module: project_working_time_task_portal
#: model:ir.model.fields,help:project_working_time_task_portal.field_project_task__total_billable_hours_spent
msgid ""
"Billable time spent on this task and its sub-tasks (and their own sub-"
"tasks)."
msgstr ""
"Temps facturable passé sur cette tâche et ses sous-tâches (et leurs propres sous-"
"tâches)."
#. module: project_working_time_task_portal #. module: project_working_time_task_portal
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form #: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form
msgid "Non Billable Effective Days" msgid "Non Billable Effective Days"
@@ -78,6 +87,15 @@ msgstr "Jours passés non facturables"
msgid "Non Billable Effective Hours" msgid "Non Billable Effective Hours"
msgstr "Heures passées non facturables" msgstr "Heures passées non facturables"
#. module: project_working_time_task_portal
#: model:ir.model.fields,help:project_working_time_task_portal.field_project_task__total_non_billable_hours_spent
msgid ""
"Non billable time spent on this task and its sub-tasks (and their own sub-"
"tasks)."
msgstr ""
"Temps non facturable passé sur cette tâche et ses sous-tâches (et leurs propres sous-"
"tâches)."
#. module: project_working_time_task_portal #. module: project_working_time_task_portal
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.portal_my_task_remaining_hours #: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.portal_my_task_remaining_hours
msgid "Remaining Hours:" msgid "Remaining Hours:"
@@ -116,9 +134,32 @@ msgstr "Sous-tâches heures passées non facturables"
msgid "Task" msgid "Task"
msgstr "Tâche" msgstr "Tâche"
#. module: project_working_time_task_portal
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form
msgid "Total Billable Days"
msgstr "Total des jours facturables"
#. module: project_working_time_task_portal
#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__total_billable_hours_spent
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form
msgid "Total Billable Hours"
msgstr "Total des heures facturables"
#. module: project_working_time_task_portal #. module: project_working_time_task_portal
#: model:ir.model.fields,help:project_working_time_task_portal.field_project_task__billable_remaining_hours #: model:ir.model.fields,help:project_working_time_task_portal.field_project_task__billable_remaining_hours
msgid "" msgid ""
"Total Billable remaining time (without exclude_from_sale_order timesheet " "Total Billable remaining time (without exclude_from_sale_order timesheet "
"lines), can be re-estimated periodically by the assignee of the task." "lines), can be re-estimated periodically by the assignee of the task."
msgstr "" msgstr ""
"Nombre d'heures allouées moins le nombre d'heures passées facturées."
#. module: project_working_time_task_portal
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form
msgid "Total Non Billable Days"
msgstr "Total des jours non facturables"
#. module: project_working_time_task_portal
#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__total_non_billable_hours_spent
#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form
msgid "Total Non Billable Hours"
msgstr "Total des heures non facturables"

View File

@@ -45,6 +45,20 @@ class Task(models.Model):
recursive=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') @api.depends('timesheet_ids.unit_amount')
def _compute_billable_effective_hours(self): def _compute_billable_effective_hours(self):
if not any(self._ids): if not any(self._ids):
@@ -94,3 +108,17 @@ class Task(models.Model):
task.billable_progress = round(100.0 * task_total_hours / task.planned_hours, 2) task.billable_progress = round(100.0 * task_total_hours / task.planned_hours, 2)
else: else:
task.billable_progress = 0.0 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
)

View File

@@ -31,6 +31,24 @@
</span> </span>
<field name="subtask_non_billable_effective_hours" widget="timesheet_uom" class="mt-2" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" nolabel="1"/> <field name="subtask_non_billable_effective_hours" widget="timesheet_uom" class="mt-2" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" nolabel="1"/>
</xpath> </xpath>
<xpath expr="//field[@name='total_hours_spent']" position="after">
<span attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}">
<label for="total_billable_hours_spent" string="Total Billable Hours"
attrs="{'invisible': [('encode_uom_in_days', '=', True)]}"/>
<label for="total_billable_hours_spent" string="Total Billable Days"
attrs="{'invisible': [('encode_uom_in_days', '=', False)]}"/>
</span>
<field name="total_billable_hours_spent" widget="timesheet_uom" nolabel="1"
attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" />
<span attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}">
<label for="total_non_billable_hours_spent" string="Total Non Billable Hours"
attrs="{'invisible': [('encode_uom_in_days', '=', True)]}"/>
<label for="total_non_billable_hours_spent" string="Total Non Billable Days"
attrs="{'invisible': [('encode_uom_in_days', '=', False)]}"/>
</span>
<field name="total_non_billable_hours_spent" widget="timesheet_uom" nolabel="1"
attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" />
</xpath>
<xpath expr="//field[@name='remaining_hours']" position="after"> <xpath expr="//field[@name='remaining_hours']" position="after">
<span> <span>
<label class="font-weight-bold text-danger" for="billable_remaining_hours" string="Billable Remaining Hours" attrs="{'invisible': ['|', '|', ('planned_hours', '=', 0.0), ('encode_uom_in_days', '=', True), ('billable_remaining_hours', '&gt;=', 0)]}"/> <label class="font-weight-bold text-danger" for="billable_remaining_hours" string="Billable Remaining Hours" attrs="{'invisible': ['|', '|', ('planned_hours', '=', 0.0), ('encode_uom_in_days', '=', True), ('billable_remaining_hours', '&gt;=', 0)]}"/>