[IMP] hr,sale(_timesheet): clean duration in days

The purpose of this task is there are several places where the
duration is expressed in hours even though the encoding unit
is in Days. This creates inconsistencies.

In this commit, we convert hours into days when the encoding
unit is in Days. Also, we changed the string of the fields
according to the encoding unit.

closes odoo/odoo#70512

Task-id: 2512950
Related: odoo/enterprise#18197
Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
This commit is contained in:
Nidhi Patel
2021-06-23 11:02:07 +00:00
parent 4e006fb831
commit e159698b96
9 changed files with 91 additions and 14 deletions
+1
View File
@@ -32,6 +32,7 @@ up a management by affair.
'views/project_update_templates.xml',
'views/hr_timesheet_portal_templates.xml',
'report/hr_timesheet_report_view.xml',
'report/project_report_view.xml',
'report/report_timesheet_templates.xml',
'views/hr_views.xml',
'data/hr_timesheet_data.xml',
+4 -3
View File
@@ -218,16 +218,17 @@ class Task(models.Model):
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'):
if view_type in ['tree', 'pivot', 'graph'] 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):
def _apply_time_label(self, view_arch, related_model=None):
doc = etree.XML(view_arch)
Model = self.env[related_model or self._name]
encoding_uom = self.env.company.timesheet_encode_uom_id
for node in doc.xpath("//field[@widget='timesheet_uom'][not(@string)] | //field[@widget='timesheet_uom_no_toggle'][not(@string)]"):
name_with_uom = re.sub(_('Hours') + "|Hours", encoding_uom.name or '', self._fields[node.get('name')]._description_string(self.env), flags=re.IGNORECASE)
name_with_uom = re.sub(_('Hours') + "|Hours", encoding_uom.name or '', Model._fields[node.get('name')]._description_string(self.env), flags=re.IGNORECASE)
node.set('string', name_with_uom)
return etree.tostring(doc, encoding='unicode')
+8 -1
View File
@@ -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 fields, models, api
class ReportProjectTaskUser(models.Model):
@@ -25,3 +25,10 @@ class ReportProjectTaskUser(models.Model):
t.effective_hours,
planned_hours
"""
@api.model
def _fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
result = super(ReportProjectTaskUser, self)._fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
if view_type in ['pivot', 'graph'] and self.env.company.timesheet_encode_uom_id == self.env.ref('uom.product_uom_day'):
result['arch'] = self.env['project.task']._apply_time_label(result['arch'], related_model=self._name)
return result
@@ -6,12 +6,27 @@
<field name="model">report.project.task.user</field>
<field name="inherit_id" ref="project.view_task_project_user_graph" />
<field name="arch" type="xml">
<graph string="Tasks Analysis" type="bar" sample="1" disable_linking="1">
<field name="project_id" position="after">
<field name="hours_planned" type="measure"/>
<field name="remaining_hours" type="measure"/>
</field>
</graph>
<xpath expr="//graph" position="attributes">
<attribute name="js_class">hr_timesheet_graphview</attribute>
</xpath>
<xpath expr="//field[@name='project_id']" position='after'>
<field name="hours_planned" widget="timesheet_uom" type="measure"/>
<field name="hours_effective" widget="timesheet_uom" type="measure"/>
<field name="remaining_hours" widget="timesheet_uom" type="measure"/>
</xpath>
</field>
</record>
<record id="view_task_project_user_pivot_inherited" model="ir.ui.view">
<field name="name">report.project.task.user.pivot.inherited</field>
<field name="model">report.project.task.user</field>
<field name="inherit_id" ref="project.view_task_project_user_pivot"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='project_id']" position='after'>
<field name="hours_planned" widget="timesheet_uom" type="measure"/>
<field name="hours_effective" widget="timesheet_uom" type="measure"/>
<field name="remaining_hours" widget="timesheet_uom" type="measure"/>
</xpath>
</field>
</record>
</data>
@@ -15,8 +15,10 @@ odoo.define('hr_timesheet.GraphView', function (require) {
const currentCompanyId = session.user_context.allowed_company_ids[0];
const currentCompany = session.user_companies.allowed_companies[currentCompanyId];
const currentCompanyTimesheetUOMFactor = currentCompany.timesheet_uom_factor || 1;
const fields = ['unit_amount', 'effective_hours', 'planned_hours', 'remaining_hours', 'total_hours_spent', 'subtask_effective_hours',
'overtime', 'number_hours', 'difference', 'hours_effective', 'hours_planned', 'timesheet_unit_amount'];
if (this.chart.measure === 'unit_amount' && currentCompanyTimesheetUOMFactor !== 1) {
if (fields.includes(this.chart.measure) && currentCompanyTimesheetUOMFactor !== 1) {
// recalculate the Duration values according to the timesheet_uom_factor
this.chart.dataPoints.forEach(function (dataPt) {
dataPt.value *= currentCompanyTimesheetUOMFactor;
@@ -37,7 +37,14 @@
<tfoot>
<tr>
<th colspan="3"></th>
<th class="text-right">Total Hours: <span t-esc="round(sum(timesheets.mapped('unit_amount')), 2)" t-options='{"widget": "float_time"}'/></th>
<th class="text-right">
<t t-if="is_uom_day">
Total Days: <span t-esc="timesheets._convert_hours_to_days(round(sum(timesheets.mapped('unit_amount')), 2))" t-options='{"widget": "timesheet_uom"}'/>
</t>
<t t-else="">
Total Hours: <span t-esc="round(sum(timesheets.mapped('unit_amount')), 2)" t-options='{"widget": "float_time"}'/>
</t>
</th>
</tr>
</tfoot>
</table>
@@ -287,5 +287,40 @@
</field>
</record>
<record id="project_task_view_graph" model="ir.ui.view">
<field name="name">project.task.view.graph.inherited</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_project_task_graph"/>
<field name="arch" type="xml">
<xpath expr="//graph" position="attributes">
<attribute name="js_class">hr_timesheet_graphview</attribute>
</xpath>
<xpath expr="//field[@name='stage_id']" position='after'>
<field name="planned_hours" widget="timesheet_uom" type="measure"/>
<field name="remaining_hours" widget="timesheet_uom" type="measure"/>
<field name="effective_hours" widget="timesheet_uom" type="measure"/>
<field name="total_hours_spent" widget="timesheet_uom" type="measure"/>
<field name="overtime" widget="timesheet_uom" type="measure"/>
<field name="subtask_effective_hours" widget="timesheet_uom" type="measure"/>
</xpath>
</field>
</record>
<record id="project_task_view_pivot" model="ir.ui.view">
<field name="name">project.task.view.pivot.inherited</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_project_task_pivot"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='stage_id']" position='after'>
<field name="planned_hours" widget="timesheet_uom" type="measure"/>
<field name="remaining_hours" widget="timesheet_uom" type="measure"/>
<field name="effective_hours" widget="timesheet_uom" type="measure"/>
<field name="total_hours_spent" widget="timesheet_uom" type="measure"/>
<field name="overtime" widget="timesheet_uom" type="measure"/>
<field name="subtask_effective_hours" widget="timesheet_uom" type="measure"/>
</xpath>
</field>
</record>
</data>
</odoo>
@@ -11,6 +11,7 @@
<field name="amount_untaxed_invoiced" type="measure"/>
<field name="timesheet_cost" type="measure"/>
<field name="margin" type="measure"/>
<field name="timesheet_unit_amount" widget="timesheet_uom" type="measure"/>
</pivot>
</field>
</record>
@@ -19,7 +20,7 @@
<field name="name">project.profitability.report.graph</field>
<field name="model">project.profitability.report</field>
<field name="arch" type="xml">
<graph string="Profitability Analysis" type="bar" sample="1" disable_linking="1">
<graph string="Profitability Analysis" type="bar" sample="1" disable_linking="1" js_class="hr_timesheet_graphview">
<field name="project_id" type="row"/>
<field name="product_id" type="col"/>
<field name="amount_untaxed_to_invoice" type="measure"/>
@@ -27,6 +28,7 @@
<field name="timesheet_cost" type="measure"/>
<field name="other_revenues" type="measure"/>
<field name="margin" type="measure"/>
<field name="timesheet_unit_amount" widget="timesheet_uom" type="measure"/>
</graph>
</field>
</record>
@@ -22,7 +22,14 @@
<em class="font-weight-normal text-muted">Timesheets for sales order item:</em>
<span t-field="sol.display_name"/>
<t t-if="sol.remaining_hours_available">
<span class="text-muted font-weight-normal">(<span t-field="sol.product_uom_qty" t-options='{"widget": "float_time"}'></span> <span t-field="sol.product_uom.display_name"></span> Ordered, <span t-field="sol.remaining_hours" t-options='{"widget": "float_time"}'></span> <span t-field="sol.product_uom.display_name"></span> Remaining)</span>
<span class="text-muted font-weight-normal">
<t t-if="is_uom_day">
(<span t-esc="timesheets._convert_hours_to_days(sol.product_uom_qty)" t-options='{"widget": "timesheet_uom"}'></span> Days Ordered, <span t-esc="timesheets._convert_hours_to_days(sol.remaining_hours)" t-options='{"widget": "timesheet_uom"}'></span> Days Remaining)
</t>
<t t-else="">
(<span t-field="sol.product_uom_qty" t-options='{"widget": "float_time"}'></span> <span t-field="sol.product_uom.display_name"></span> Ordered, <span t-field="sol.remaining_hours" t-options='{"widget": "float_time"}'></span> <span t-field="sol.product_uom.display_name"></span> Remaining)
</t>
</span>
</t>
</t>
</th>