diff --git a/addons/mrp/static/src/widgets/timer.js b/addons/mrp/static/src/widgets/timer.js index 811d69576e4..c8111f32251 100644 --- a/addons/mrp/static/src/widgets/timer.js +++ b/addons/mrp/static/src/widgets/timer.js @@ -1,37 +1,47 @@ /** @odoo-module **/ import { registry } from "@web/core/registry"; -import { formatFloatTime } from "@web/views/fields/formatters"; +import { parseFloatTime } from "@web/views/fields/parsers"; +import { useInputField } from "@web/views/fields/input_field_hook"; const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl; export class MrpTimer extends Component { setup() { - super.setup(); this.state = useState({ + // duration is expected to be given in minutes duration: - this.props.duration !== undefined - ? this.props.duration - : this.props.record.data.duration, + this.props.value !== undefined ? this.props.value : this.props.record.data.duration, + }); + useInputField({ + getValue: () => this.durationFormatted, + refName: "numpadDecimal", + parse: (v) => parseFloatTime(v), }); - const newLocal = this; this.ongoing = this.props.ongoing !== undefined - ? newLocal.props.ongoing + ? this.props.ongoing : this.props.record.data.is_user_working; onWillStart(() => this._runTimer()); onWillUpdateProps((nextProps) => { - this.ongoing = nextProps.ongoing; - this._runTimer(); + this.state.duration = nextProps.value; + const newOngoing = + "ongoing" in nextProps + ? nextProps.ongoing + : "record" in nextProps && nextProps.record.data.is_user_working; + const rerun = !this.ongoing && newOngoing; + this.ongoing = newOngoing; + if (rerun) { + this._runTimer(); + } }); onWillDestroy(() => clearTimeout(this.timer)); } - get duration() { - // formatFloatTime except 1,5 = 1h30min but in mrp case 1,5 = 1min30 - return formatFloatTime(this.state.duration / 60, { displaySeconds: true }); + get durationFormatted() { + return this._formatMinutes(); } _runTimer() { @@ -42,6 +52,24 @@ export class MrpTimer extends Component { }, 1000); } } + + _formatMinutes() { + let value = this.state.duration; + if (value === false) { + return ""; + } + const isNegative = value < 0; + if (isNegative) { + value = Math.abs(value); + } + let min = Math.floor(value); + // Although looking quite overkill, the following line ensures that we do + // not have float issues while still considering that 59s is 00:00. + let sec = Math.floor(Math.round((value % 1) * 60)); + sec = `${sec}`.padStart(2, "0"); + min = `${min}`.padStart(2, "0"); + return `${isNegative ? "-" : ""}${min}:${sec}`; + } } MrpTimer.supportedTypes = ["float"]; diff --git a/addons/mrp/static/src/widgets/timer.xml b/addons/mrp/static/src/widgets/timer.xml index 9b8fb491ffe..607f433009f 100644 --- a/addons/mrp/static/src/widgets/timer.xml +++ b/addons/mrp/static/src/widgets/timer.xml @@ -1,6 +1,7 @@ - + + diff --git a/addons/mrp/static/tests/mrp_tests_widgets.js b/addons/mrp/static/tests/mrp_tests_widgets.js index aed9ad5ddd5..53d271fc68f 100644 --- a/addons/mrp/static/tests/mrp_tests_widgets.js +++ b/addons/mrp/static/tests/mrp_tests_widgets.js @@ -30,13 +30,13 @@ QUnit.module("Mrp", (hooks) => { serverData, resModel: "foo", resId: 1, - arch: '
', + arch: '
', }); assert.strictEqual( target.querySelector(".o_field_mrp_timer").textContent, - "02:30:30", - "should contain hours and be correctly set base on minutes seconds" + "150:30", + "should not contain hours and be correctly set base on minutes seconds" ); }); });