[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:
@@ -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',
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user