From 82f0a2ef3158c406191a72346c79e7cbff6b536b Mon Sep 17 00:00:00 2001 From: Boris Gallet Date: Wed, 20 Dec 2023 11:50:33 +0100 Subject: [PATCH] [IMP]project_working_time_task_portal : add billable time --- project_working_time_task_portal/README.rst | 4 +- project_working_time_task_portal/__init__.py | 1 + .../__manifest__.py | 12 +-- project_working_time_task_portal/i18n/fr.po | 40 ++++++++- .../models/__init__.py | 1 + .../models/billable_time.py | 86 +++++++++++++++++++ .../views/hr_timesheet_portal.xml | 24 +++++- .../views/hr_timesheet_view_task_form2.xml | 32 +++++++ 8 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 project_working_time_task_portal/models/__init__.py create mode 100644 project_working_time_task_portal/models/billable_time.py create mode 100644 project_working_time_task_portal/views/hr_timesheet_view_task_form2.xml diff --git a/project_working_time_task_portal/README.rst b/project_working_time_task_portal/README.rst index 42295a1..b1c3f89 100644 --- a/project_working_time_task_portal/README.rst +++ b/project_working_time_task_portal/README.rst @@ -2,7 +2,7 @@ project_working_time_task_portal =============== -add planned hours and remaining hours in the task portal view +add billable planned hours and billable remaining hours in the task portal view so the portal user only see billable timesheet lines Installation ============ @@ -18,7 +18,7 @@ None yet. Bug Tracker =========== -Bugs are tracked on `our issues website `_. In case of +Bugs are tracked on `our issues website `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. diff --git a/project_working_time_task_portal/__init__.py b/project_working_time_task_portal/__init__.py index e69de29..9a7e03e 100644 --- a/project_working_time_task_portal/__init__.py +++ b/project_working_time_task_portal/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/project_working_time_task_portal/__manifest__.py b/project_working_time_task_portal/__manifest__.py index 5ebeca1..35cc17e 100644 --- a/project_working_time_task_portal/__manifest__.py +++ b/project_working_time_task_portal/__manifest__.py @@ -3,16 +3,18 @@ { "name": "project_working_time_task_portal", - "version": "14.0.0.0", + "version": "14.0.2.0.0", "author": "Elabore", "website": "https://elabore.coop", "maintainer": "Boris Gallet", "license": "AGPL-3", "category": "tools", - "summary": "add planned hours and remaining hours in the task portal view", + "summary": "add billable planned hours and billable remaining hours in the task portal view so the portal user only see billable timesheet lines", # any module necessary for this one to work correctly "depends": [ "base", + "project", + "sale_timesheet_line_exclude" ], "qweb": [], "external_dependencies": { @@ -20,11 +22,9 @@ }, # always loaded "data": [ - # "security/security.xml", - # "security/ir.model.access.csv", - "views/hr_timesheet_portal.xml", "views/assets.xml", - # "data/data.xml", + "views/hr_timesheet_portal.xml", + "views/hr_timesheet_view_task_form2.xml" ], # only loaded in demonstration mode "demo": [], diff --git a/project_working_time_task_portal/i18n/fr.po b/project_working_time_task_portal/i18n/fr.po index 61decc8..a6c8b5d 100644 --- a/project_working_time_task_portal/i18n/fr.po +++ b/project_working_time_task_portal/i18n/fr.po @@ -33,4 +33,42 @@ msgstr "Heures Planifiées Sous-tâches: " #. module: project_working_time_task_portal #: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.portal_my_task_remaining_hours msgid "Remaining Hours:" -msgstr "Heures restantes:" \ No newline at end of file +msgstr "Heures restantes:" + +#. module: project_working_time_task_portal +#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__billable_remaining_hours +#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form +msgid "Billable Remaining Hours" +msgstr "Heures restantes facturables" + +#. 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 "Billable Remaining Days" +msgstr "Jours restants facturables" + +#. 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 "Billable Effective Days" +msgstr "Jours passés facturables" + +#. module: project_working_time_task_portal +#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__billable_effective_hours +#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form +msgid "Billable Effective Hours" +msgstr "Heures passées facturables" + +#. module: project_working_time_task_portal +#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__subtask_billable_effective_hours +msgid "Subtask Billable Effective Hours" +msgstr "Heures passées facturables Sous-tâches" + +#. 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 "Non Billable Effective Days" +msgstr "Jours passés non facturables" + +#. module: project_working_time_task_portal +#: model:ir.model.fields,field_description:project_working_time_task_portal.field_project_task__non_billable_effective_hours +#: model_terms:ir.ui.view,arch_db:project_working_time_task_portal.project_working_time_view_task_form +msgid "Non Billable Effective Hours" +msgstr "Heures passées non facturables" \ No newline at end of file diff --git a/project_working_time_task_portal/models/__init__.py b/project_working_time_task_portal/models/__init__.py new file mode 100644 index 0000000..13c9eb7 --- /dev/null +++ b/project_working_time_task_portal/models/__init__.py @@ -0,0 +1 @@ +from . import billable_time \ No newline at end of file diff --git a/project_working_time_task_portal/models/billable_time.py b/project_working_time_task_portal/models/billable_time.py new file mode 100644 index 0000000..fb5d5fe --- /dev/null +++ b/project_working_time_task_portal/models/billable_time.py @@ -0,0 +1,86 @@ +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, + compute_sudo=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, + compute_sudo=True, + ) + + @api.depends('timesheet_ids.unit_amount') + 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('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 \ No newline at end of file diff --git a/project_working_time_task_portal/views/hr_timesheet_portal.xml b/project_working_time_task_portal/views/hr_timesheet_portal.xml index 71d94c2..301a8be 100644 --- a/project_working_time_task_portal/views/hr_timesheet_portal.xml +++ b/project_working_time_task_portal/views/hr_timesheet_portal.xml @@ -13,10 +13,10 @@ - +
Progress: - +
%
@@ -27,13 +27,31 @@ + + + \ No newline at end of file diff --git a/project_working_time_task_portal/views/hr_timesheet_view_task_form2.xml b/project_working_time_task_portal/views/hr_timesheet_view_task_form2.xml new file mode 100644 index 0000000..53141a4 --- /dev/null +++ b/project_working_time_task_portal/views/hr_timesheet_view_task_form2.xml @@ -0,0 +1,32 @@ + + + + + project.working.time.view.task.form + project.task + + + + + + + + + + + + + + + + + + + + \ No newline at end of file