diff options
| -rw-r--r-- | addons/hr_timesheet/controllers/portal.py | 1 | ||||
| -rw-r--r-- | addons/hr_timesheet/controllers/project.py | 1 | ||||
| -rw-r--r-- | addons/hr_timesheet/models/hr_timesheet.py | 12 | ||||
| -rw-r--r-- | addons/hr_timesheet/models/project.py | 39 | ||||
| -rw-r--r-- | addons/hr_timesheet/models/res_config_settings.py | 9 | ||||
| -rw-r--r-- | addons/hr_timesheet/report/report_timesheet_templates.xml | 38 | ||||
| -rw-r--r-- | addons/hr_timesheet/static/src/js/timesheet_factor.js | 20 | ||||
| -rw-r--r-- | addons/hr_timesheet/static/src/scss/timesheets_task_form.scss | 4 | ||||
| -rw-r--r-- | addons/hr_timesheet/views/assets.xml | 2 | ||||
| -rw-r--r-- | addons/hr_timesheet/views/hr_timesheet_portal_templates.xml | 8 | ||||
| -rw-r--r-- | addons/hr_timesheet/views/project_portal_templates.xml | 8 | ||||
| -rw-r--r-- | addons/hr_timesheet/views/project_views.xml | 71 | ||||
| -rw-r--r-- | addons/hr_timesheet/views/res_config_settings_views.xml | 3 |
13 files changed, 181 insertions, 35 deletions
diff --git a/addons/hr_timesheet/controllers/portal.py b/addons/hr_timesheet/controllers/portal.py index aceb00e3232..f103e80970a 100644 --- a/addons/hr_timesheet/controllers/portal.py +++ b/addons/hr_timesheet/controllers/portal.py @@ -141,5 +141,6 @@ class TimesheetCustomerPortal(CustomerPortal): 'searchbar_groupby': searchbar_groupby, 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), 'filterby': filterby, + 'is_uom_day': request.env['account.analytic.line']._is_timesheet_encode_uom_day(), }) return request.render("hr_timesheet.portal_my_timesheets", values) diff --git a/addons/hr_timesheet/controllers/project.py b/addons/hr_timesheet/controllers/project.py index dd377160d6b..31fbe2f326c 100644 --- a/addons/hr_timesheet/controllers/project.py +++ b/addons/hr_timesheet/controllers/project.py @@ -22,4 +22,5 @@ class ProjectCustomerPortal(CustomerPortal): timesheets_by_subtask[timesheet.task_id] |= timesheet values['timesheets'] = timesheets values['timesheets_by_subtask'] = timesheets_by_subtask + values['is_uom_day'] = request.env['account.analytic.line']._is_timesheet_encode_uom_day() return values diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index 69ed16ed4b2..24458df59a5 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -189,3 +189,15 @@ class AccountAnalyticLine(models.Model): 'amount': amount_converted, }) return result + + def _is_timesheet_encode_uom_day(self): + company_uom = self.env.company.timesheet_encode_uom_id + return company_uom == self.env.ref('uom.product_uom_day') + + def _convert_hours_to_days(self, time): + uom_hour = self.env.ref('uom.product_uom_hour') + uom_day = self.env.ref('uom.product_uom_day') + return round(uom_hour._compute_quantity(time, uom_day, raise_if_failure=False), 2) + + def _get_timesheet_time_day(self): + return self._convert_hours_to_days(self.unit_amount) diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py index 4fbe868b2de..fdd3b0210ec 100644 --- a/addons/hr_timesheet/models/project.py +++ b/addons/hr_timesheet/models/project.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from lxml import etree + from odoo import models, fields, api, _ from odoo.exceptions import UserError, ValidationError, RedirectWarning @@ -24,6 +26,10 @@ class Project(models.Model): total_timesheet_time = fields.Integer( compute='_compute_total_timesheet_time', help="Total number of time (in the proper UoM) recorded in the project, rounded to the unit.") + encode_uom_in_days = fields.Boolean(compute='_compute_encode_uom_in_days') + + def _compute_encode_uom_in_days(self): + self.encode_uom_in_days = self.env.company.timesheet_encode_uom_id == self.env.ref('uom.product_uom_day') @api.depends('analytic_account_id') def _compute_allow_timesheets(self): @@ -106,6 +112,13 @@ class Task(models.Model): overtime = fields.Float(compute='_compute_progress_hours', store=True) subtask_effective_hours = fields.Float("Sub-tasks Hours Spent", compute='_compute_subtask_effective_hours', store=True, help="Time spent on the sub-tasks (and their own sub-tasks) of this task.") timesheet_ids = fields.One2many('account.analytic.line', 'task_id', 'Timesheets') + encode_uom_in_days = fields.Boolean(compute='_compute_encode_uom_in_days', default=lambda self: self._uom_in_days()) + + def _uom_in_days(self): + return self.env.company.timesheet_encode_uom_id == self.env.ref('uom.product_uom_day') + + def _compute_encode_uom_in_days(self): + self.encode_uom_in_days = self._uom_in_days() @api.depends('project_id.analytic_account_id.active') def _compute_analytic_account_active(self): @@ -180,7 +193,10 @@ class Task(models.Model): if self.env.context.get('hr_timesheet_display_remaining_hours'): name_mapping = dict(super().name_get()) for task in self: - if task.allow_timesheets and task.planned_hours > 0: + if task.allow_timesheets and task.planned_hours > 0 and task.encode_uom_in_days: + days_left = _("(%s days remaining)") % task._convert_hours_to_days(task.remaining_hours) + name_mapping[task.id] = name_mapping.get(task.id, '') + " ‒ " + days_left + elif task.allow_timesheets and task.planned_hours > 0: hours, mins = (str(int(duration)).rjust(2, '0') for duration in divmod(abs(task.remaining_hours) * 60, 60)) hours_left = _( "(%(sign)s%(hours)s:%(minutes)s remaining)", @@ -197,8 +213,24 @@ class Task(models.Model): """ Set the correct label for `unit_amount`, depending on company UoM """ result = super(Task, self)._fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) result['arch'] = self.env['account.analytic.line']._apply_timesheet_label(result['arch']) + + if view_type == 'tree' and self.env.company.timesheet_encode_uom_id == self.env.ref('uom.product_uom_day'): + result['arch'] = self._apply_time_label(result['arch']) return result + @api.model + def _apply_time_label(self, view_arch): + doc = etree.XML(view_arch) + encoding_uom = self.env.company.timesheet_encode_uom_id + + for node in doc.xpath("//field[@name='planned_hours'][@widget='timesheet_uom'][not(@string)]"): + node.set('string', _('Planned %s') % encoding_uom.name or '') + for node in doc.xpath("//field[@name='effective_hours'][@widget='timesheet_uom'][not(@string)]"): + node.set('string', _('%s Spent') % encoding_uom.name or '') + for node in doc.xpath("//field[@name='remaining_hours'][@widget='timesheet_uom'][not(@string)]"): + node.set('string', _('Remaining %s') % encoding_uom.name or '') + return etree.tostring(doc, encoding='unicode') + def unlink(self): """ If some tasks to unlink have some timesheets entries, these @@ -216,3 +248,8 @@ class Task(models.Model): warning_msg, self.env.ref('hr_timesheet.timesheet_action_task').id, _('See timesheet entries'), {'active_ids': tasks_with_timesheets.ids}) return super(Task, self).unlink() + + def _convert_hours_to_days(self, time): + uom_hour = self.env.ref('uom.product_uom_hour') + uom_day = self.env.ref('uom.product_uom_day') + return round(uom_hour._compute_quantity(time, uom_day, raise_if_failure=False), 2) diff --git a/addons/hr_timesheet/models/res_config_settings.py b/addons/hr_timesheet/models/res_config_settings.py index f8e8f00621c..68ed5bd2df1 100644 --- a/addons/hr_timesheet/models/res_config_settings.py +++ b/addons/hr_timesheet/models/res_config_settings.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models +from odoo import api, fields, models class ResConfigSettings(models.TransientModel): @@ -20,3 +20,10 @@ class ResConfigSettings(models.TransientModel): and widgets to help the encoding. All reporting will still be expressed in hours (default value).""") timesheet_min_duration = fields.Integer('Minimal duration', default=15, config_parameter='hr_timesheet.timesheet_min_duration') timesheet_rounding = fields.Integer('Rounding up', default=15, config_parameter='hr_timesheet.timesheet_rounding') + is_encode_uom_days = fields.Boolean(compute='_compute_is_encode_uom_days') + + @api.depends('timesheet_encode_uom_id') + def _compute_is_encode_uom_days(self): + product_uom_day = self.env.ref('uom.product_uom_day') + for settings in self: + settings.is_encode_uom_days = settings.timesheet_encode_uom_id == product_uom_day diff --git a/addons/hr_timesheet/report/report_timesheet_templates.xml b/addons/hr_timesheet/report/report_timesheet_templates.xml index 38fc2f4e82e..7dac6e7430d 100644 --- a/addons/hr_timesheet/report/report_timesheet_templates.xml +++ b/addons/hr_timesheet/report/report_timesheet_templates.xml @@ -20,15 +20,19 @@ <div class="row" style="margin-top:10px;"> <div class="col-lg-12"> + <t t-set='is_uom_day' t-value='docs._is_timesheet_encode_uom_day()'/> <table class="table table-sm"> <thead> <tr> - <th><span>Date</span></th> - <th><span>Responsible</span></th> - <th><span>Description</span></th> - <th t-if="show_project"><span>Project</span></th> - <th t-if="show_task"><span>Task</span></th> - <th class="text-right"><span>Time</span></th> + <th class="align-middle"><span>Date</span></th> + <th class="align-middle"><span>Responsible</span></th> + <th class="align-middle"><span>Description</span></th> + <th class="align-middle" t-if="show_project"><span>Project</span></th> + <th class="align-middle" t-if="show_task"><span>Task</span></th> + <th class="text-right"> + <span t-if="is_uom_day">Time Spent (Days)</span> + <span t-else="">Time Spent (Hours)</span> + </th> </tr> </thead> <tbody> @@ -49,16 +53,24 @@ <t t-if="l.task_id"><span t-field="l.task_id.name"/></t> </td> <td class="text-right"> - <span t-field="l.unit_amount" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/> + <span t-if="is_uom_day" t-esc="l._get_timesheet_time_day()" t-options="{'widget': 'timesheet_uom'}"/> + <span t-else="" t-field="l.unit_amount" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/> </td> </tr> <tr> - <td /> - <td /> - <td t-if="show_project"/> - <td t-if="show_task"/> - <td class="text-right"><strong>Total</strong></td> - <td class="text-right"><strong t-esc="sum(docs.mapped('unit_amount'))" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/></td> + <t t-set="nbCols" t-value="4"/> + <t t-if="show_project" t-set="nbCols" t-value="nbCols + 1"/> + <t t-if="show_task" t-set="nbCols" t-value="nbCols + 1"/> + <td class="text-right" t-attf-colspan="{{nbCols}}"> + <strong t-if="is_uom_day"> + <span style="margin-right: 15px;">Total (Days)</span> + <t t-esc="docs._convert_hours_to_days(sum(docs.mapped('unit_amount')))" t-options="{'widget': 'timesheet_uom'}"/> + </strong> + <strong t-else=""> + <span style="margin-right: 15px;">Total (Hours)</span> + <t t-esc="sum(docs.mapped('unit_amount'))" t-options="{'widget': 'duration', 'digital': True, 'unit': 'hour', 'round': 'minute'}"/> + </strong> + </td> </tr> </tbody> </table> diff --git a/addons/hr_timesheet/static/src/js/timesheet_factor.js b/addons/hr_timesheet/static/src/js/timesheet_factor.js new file mode 100644 index 00000000000..def165e03fd --- /dev/null +++ b/addons/hr_timesheet/static/src/js/timesheet_factor.js @@ -0,0 +1,20 @@ +odoo.define('hr_timesheet.timesheet_factor', function (require) { +'use strict'; + +const timesheetUomFields = require('hr_timesheet.timesheet_uom'); +const fieldUtils = require('web.field_utils'); +const fieldRegistry = require('web.field_registry'); + +fieldRegistry.add('timesheet_factor', timesheetUomFields.FieldTimesheetFactor); + +fieldUtils.format.timesheet_factor = function(value, field, options) { + const formatter = fieldUtils.format[timesheetUomFields.FieldTimesheetFactor.prototype.formatType]; + return formatter(value, field, options); +}; + +fieldUtils.parse.timesheet_factor = function(value, field, options) { + const parser = fieldUtils.parse[timesheetUomFields.FieldTimesheetFactor.prototype.formatType]; + return parser(value, field, options); +}; + +}); diff --git a/addons/hr_timesheet/static/src/scss/timesheets_task_form.scss b/addons/hr_timesheet/static/src/scss/timesheets_task_form.scss new file mode 100644 index 00000000000..8a7e3b78477 --- /dev/null +++ b/addons/hr_timesheet/static/src/scss/timesheets_task_form.scss @@ -0,0 +1,4 @@ +.o_form_subtask_button { + border: none; + padding-left: 0px; +} diff --git a/addons/hr_timesheet/views/assets.xml b/addons/hr_timesheet/views/assets.xml index 816f36f5c53..bb997241062 100644 --- a/addons/hr_timesheet/views/assets.xml +++ b/addons/hr_timesheet/views/assets.xml @@ -2,8 +2,10 @@ <odoo> <template id="assets_backend" name="timesheet assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> + <link type="text/scss" href="/hr_timesheet/static/src/scss/timesheets_task_form.scss" rel="stylesheet"/> <script type="text/javascript" src="/hr_timesheet/static/src/js/task_with_hours.js"></script> <script type="text/javascript" src="/hr_timesheet/static/src/js/timesheet_uom.js"/> + <script type="text/javascript" src="/hr_timesheet/static/src/js/timesheet_factor.js"/> </xpath> </template> </odoo> diff --git a/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml b/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml index 3d0044a2ea9..bef7862b1e1 100644 --- a/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml +++ b/addons/hr_timesheet/views/hr_timesheet_portal_templates.xml @@ -61,7 +61,8 @@ <th t-if="not groupby == 'project'">Project</th> <th t-if="not groupby == 'task'">Task</th> <th>Description</th> - <th class="text-right">Hours Spent <small class="text-muted">(Total: <span t-esc="hours_spent" t-options='{"widget": "float_time"}'/>)</small></th> + <th t-if="is_uom_day" class="text-right">Days Spent <small class="text-muted">(Total: <span t-esc="timesheets[0]._convert_hours_to_days(hours_spent)" t-options='{"widget": "timesheet_uom"}'/>)</small></th> + <th t-else="" class="text-right">Hours Spent <small class="text-muted">(Total: <span t-esc="hours_spent" t-options='{"widget": "float_time"}'/>)</small></th> </tr> </thead> <tbody> @@ -72,7 +73,10 @@ <td t-if="not groupby == 'project'"><span t-field="timesheet.project_id"/></td> <td t-if="not groupby == 'task'"><span t-field="timesheet.task_id"/></td> <td><span t-esc="timesheet.name"/></td> - <td class="text-right"><span t-field="timesheet.unit_amount" t-options='{"widget": "float_time"}'/></td> + <td class="text-right"> + <span t-if="is_uom_day" t-esc="timesheet._get_timesheet_time_day()" t-options='{"widget": "timesheet_uom"}'/> + <span t-else= "" t-field="timesheet.unit_amount" t-options='{"widget": "float_time"}'/> + </td> </tr> </t> </tbody> diff --git a/addons/hr_timesheet/views/project_portal_templates.xml b/addons/hr_timesheet/views/project_portal_templates.xml index 19c0648db03..8f6a10e821c 100644 --- a/addons/hr_timesheet/views/project_portal_templates.xml +++ b/addons/hr_timesheet/views/project_portal_templates.xml @@ -21,14 +21,18 @@ <th>Date</th> <th>Employee</th> <th>Description</th> - <th class="text-right">Duration</th> + <th t-if="is_uom_day" class="text-right">Duration (Days)</th> + <th t-else="" class="text-right">Duration (Hours)</th> </tr> </thead> <tr t-foreach="timesheets" t-as="timesheet"> <td><t t-esc="timesheet.date" t-options='{"widget": "date"}'/></td> <td><t t-esc="timesheet.employee_id.name"/></td> <td><t t-esc="timesheet.name"/></td> - <td class="text-right"><span t-field="timesheet.unit_amount" t-options='{"widget": "float_time"}'/></td> + <td class="text-right"> + <span t-if="is_uom_day" t-esc="timesheet._get_timesheet_time_day()" t-options='{"widget": "timesheet_uom"}'/> + <span t-else="" t-field="timesheet.unit_amount" t-options='{"widget": "float_time"}'/> + </td> </tr> <tfoot> <tr> diff --git a/addons/hr_timesheet/views/project_views.xml b/addons/hr_timesheet/views/project_views.xml index 33da2be0b59..fd79f6d28b5 100644 --- a/addons/hr_timesheet/views/project_views.xml +++ b/addons/hr_timesheet/views/project_views.xml @@ -79,11 +79,26 @@ <field name="analytic_account_active" invisible="1"/> <field name="allow_timesheets" invisible="1"/> <field name="allow_subtasks" invisible="1"/> + <field name="encode_uom_in_days" invisible="1"/> <page string="Timesheets" id="timesheets_tab" attrs="{'invisible': [('allow_timesheets', '=', False)]}"> <group> <group> - <field name="planned_hours" widget="float_time"/> - <field name="subtask_planned_hours" widget="float_time" groups="project.group_subtask_project" attrs="{'invisible': ['|', ('allow_subtasks', '=', False), ('subtask_count', '=', 0)]}"/> + <label for="planned_hours" string="Initially Planned Hours" attrs="{'invisible': [('encode_uom_in_days', '=', True)]}"/> + <field name="planned_hours" widget="float_time" attrs="{'invisible': [('encode_uom_in_days', '=', True)]}" nolabel="1" /> + <label for="planned_hours" string="Initially Planned Days" attrs="{'invisible': [('encode_uom_in_days', '=', False)]}"/> + <field name="planned_hours" widget="timesheet_factor" attrs="{'invisible': [('encode_uom_in_days', '=', False)]}" nolabel="1" /> + <label for="subtask_planned_hours" groups="project.group_subtask_project" string="Sub-tasks Planned Hours" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_count', '=', 0), ('encode_uom_in_days', '=', True)]}"/> + <span class="o_row" groups="project.group_subtask_project" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_count', '=', 0), ('encode_uom_in_days', '=', True)]}"> + <field name="subtask_planned_hours" widget="float_time"/> + </span> + <label for="subtask_planned_hours" groups="project.group_subtask_project" string="Sub-tasks Planned Days" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_count', '=', 0), ('encode_uom_in_days', '=', False)]}"/> + <div class="o_row" groups="project.group_subtask_project" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_count', '=', 0), ('encode_uom_in_days', '=', False)]}"> + <field name="subtask_planned_hours" widget="timesheet_uom"/> + </div> </group> <group> <field name="progress" widget="progressbar"/> @@ -155,11 +170,34 @@ </field> <group attrs="{'invisible': [('analytic_account_active', '=', False)]}"> <group class="oe_subtotal_footer oe_right" name="project_hours"> - <field name="effective_hours" widget="float_time" /> - <button name="action_view_subtask_timesheet" string="Sub-tasks Hours Spent" type="object" class="o_td_label o_form_label oe_inline oe_link mr-0" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}"/> - <field name="subtask_effective_hours" class="mt-2" widget="float_time" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" nolabel="1"/> - <field name="total_hours_spent" widget="float_time" class="oe_subtotal_footer_separator" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" /> - <field name="remaining_hours" widget="float_time" class="oe_subtotal_footer_separator" attrs="{'invisible' : [('planned_hours', '=', 0.0)]}"/> + <span> + <label class="font-weight-bold" for="effective_hours" string="Hours Spent" attrs="{'invisible': [('encode_uom_in_days', '=', True)]}"/> + <label class="font-weight-bold" for="effective_hours" string="Days Spent" attrs="{'invisible': [('encode_uom_in_days', '=', False)]}"/> + </span> + <field name="effective_hours" widget="timesheet_uom" nolabel="1"/> + + <button name="action_view_subtask_timesheet" type="object" class="o_td_label o_form_label o_form_subtask_button oe_inline oe_link mr-0" attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}"> + <span class="text-nowrap" attrs="{'invisible' : [('encode_uom_in_days', '=', True)]}">Sub-tasks Hours Spent</span> + <span class="text-nowrap" attrs="{'invisible' : [('encode_uom_in_days', '=', False)]}">Sub-tasks Days Spent</span> + </button> + <field name="subtask_effective_hours" class="mt-2" widget="timesheet_uom" + attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" nolabel="1"/> + <span> + <label class="font-weight-bold" for="total_hours_spent" string="Total Hours" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0), ('encode_uom_in_days', '=', True)]}"/> + <label class="font-weight-bold" for="total_hours_spent" string="Total Days" + attrs="{'invisible': ['|', '|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0), ('encode_uom_in_days', '=', False)]}"/> + </span> + <field name="total_hours_spent" widget="timesheet_uom" class="oe_subtotal_footer_separator" nolabel="1" + attrs="{'invisible' : ['|', ('allow_subtasks', '=', False), ('subtask_effective_hours', '=', 0.0)]}" /> + <span> + <label class="font-weight-bold" for="remaining_hours" string="Remaining Hours" + attrs="{'invisible': ['|', ('planned_hours', '=', 0.0), ('encode_uom_in_days', '=', True)]}"/> + <label class="font-weight-bold" for="remaining_hours" string="Remaining Days" + attrs="{'invisible': ['|', ('planned_hours', '=', 0.0), ('encode_uom_in_days', '=', False)]}"/> + </span> + <field name="remaining_hours" widget="timesheet_uom" class="oe_subtotal_footer_separator" + attrs="{'invisible' : [('planned_hours', '=', 0.0)]}" nolabel="1"/> </group> </group> </page> @@ -175,11 +213,11 @@ <field name="arch" type="xml"> <field name="company_id" position="after"> <field name="allow_subtasks" invisible="1"/> - <field name="planned_hours" widget="float_time" sum="Initially Planned Hours" optional="hide"/> - <field name="effective_hours" widget="float_time" sum="Effective Hours" optional="show"/> - <field name="remaining_hours" widget="float_time" sum="Remaining Hours" optional="hide" decoration-danger="progress >= 100" decoration-warning="progress >= 80 and progress < 100"/> - <field name="subtask_effective_hours" widget="float_time" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/> - <field name="total_hours_spent" widget="float_time" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/> + <field name="planned_hours" widget="timesheet_uom" sum="Initially Planned Hours" optional="hide"/> + <field name="effective_hours" widget="timesheet_uom" sum="Effective Hours" optional="show"/> + <field name="remaining_hours" widget="timesheet_uom" sum="Remaining Hours" optional="hide" decoration-danger="progress >= 100" decoration-warning="progress >= 80 and progress < 100"/> + <field name="subtask_effective_hours" widget="timesheet_uom" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/> + <field name="total_hours_spent" widget="timesheet_uom" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" optional="hide"/> <field name="progress" widget="progressbar" optional="show" groups="hr_timesheet.group_hr_timesheet_user"/> </field> </field> @@ -217,15 +255,18 @@ <field name="remaining_hours" /> <field name="planned_hours" /> <field name="allow_timesheets"/> + <field name="encode_uom_in_days" invisible="1"/> </templates> <div class="oe_kanban_bottom_left" position="inside"> <t name="planned_hours" t-if="record.planned_hours.raw_value > 0 and record.allow_timesheets.raw_value"> <t t-set="badge" t-value=""/> <t t-set="badge" t-value="'badge-warning'" t-if="record.progress.raw_value >= 80 and record.progress.raw_value <= 100"/> <t t-set="badge" t-value="'badge-danger'" t-if="record.remaining_hours.raw_value < 0"/> - <div t-attf-class="oe_kanban_align badge {{ badge }}" title="Remaining hours"> - <field name="remaining_hours" widget="float_time" /> - </div> + <t t-set="title" t-value="'Remaining days'" t-if="record.encode_uom_in_days.raw_value"/> + <t t-set="title" t-value="'Remaining hours'" t-else=""/> + <div t-attf-class="oe_kanban_align badge {{ badge }}" t-att-title="title"> + <field name="remaining_hours" widget="timesheet_uom" /> + </div> </t> </div> </field> diff --git a/addons/hr_timesheet/views/res_config_settings_views.xml b/addons/hr_timesheet/views/res_config_settings_views.xml index 6b98fbfe0ae..ae5f5b066be 100644 --- a/addons/hr_timesheet/views/res_config_settings_views.xml +++ b/addons/hr_timesheet/views/res_config_settings_views.xml @@ -38,6 +38,7 @@ <div class="content-group"> <div class="mt16"> <field name="timesheet_encode_uom_id" options="{'no_create': True, 'no_open': True}" required="1" class="col-lg-5"/> + <field name="is_encode_uom_days" invisible="1"/> </div> </div> </div> @@ -72,7 +73,7 @@ </div> </div> </div> - <div class="col-12 col-lg-6 o_setting_box"> + <div class="col-12 col-lg-6 o_setting_box" attrs="{'invisible': [('module_project_timesheet_synchro', '=', False), ('is_encode_uom_days', '=', True)]}"> <div class="o_setting_right_pane"> <strong>Round Timesheets</strong> <div class="o_row w-30"> |
