[REF] mrp: timer to wowl
X-original-commit: 816212516340bf66e16f3fc9915293ab18f8cf4c Part-of: odoo/odoo#101905
This commit is contained in:
@@ -1,100 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import fields from 'web.basic_fields';
|
||||
import fieldUtils from 'web.field_utils';
|
||||
import field_registry from 'web.field_registry';
|
||||
import time from 'web.time';
|
||||
|
||||
var TimeCounter = fields.FieldFloatTime.extend({
|
||||
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.duration = this.record.data.duration;
|
||||
},
|
||||
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
var def = this._rpc({
|
||||
model: 'mrp.workcenter.productivity',
|
||||
method: 'search_read',
|
||||
domain: [
|
||||
['workorder_id', '=', this.record.data.id],
|
||||
['date_end', '=', false],
|
||||
],
|
||||
}).then(function (result) {
|
||||
var currentDate = new Date();
|
||||
var duration = 0;
|
||||
if (result.length > 0) {
|
||||
duration += self._getDateDifference(time.auto_str_to_date(result[0].date_start), currentDate);
|
||||
}
|
||||
var minutes = duration / 60 >> 0;
|
||||
var seconds = duration % 60;
|
||||
self.duration += minutes + seconds / 60;
|
||||
if (self.mode === 'edit') {
|
||||
self.value = self.duration;
|
||||
}
|
||||
});
|
||||
return Promise.all([this._super.apply(this, arguments), def]);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this._super.apply(this, arguments);
|
||||
clearTimeout(this.timer);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
isSet: function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compute the difference between two dates.
|
||||
*
|
||||
* @private
|
||||
* @param {string} dateStart
|
||||
* @param {string} dateEnd
|
||||
* @returns {integer} the difference in millisecond
|
||||
*/
|
||||
_getDateDifference: function (dateStart, dateEnd) {
|
||||
return moment(dateEnd).diff(moment(dateStart), 'seconds');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_renderReadonly: function () {
|
||||
if (this.record.data.is_user_working) {
|
||||
this._startTimeCounter();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_startTimeCounter: function () {
|
||||
var self = this;
|
||||
clearTimeout(this.timer);
|
||||
if (this.record.data.is_user_working) {
|
||||
this.timer = setTimeout(function () {
|
||||
self.duration += 1/60;
|
||||
self._startTimeCounter();
|
||||
}, 1000);
|
||||
} else {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
this.$el.text(fieldUtils.format.float_time(this.duration));
|
||||
},
|
||||
});
|
||||
|
||||
var FieldEmbedURLViewer = fields.FieldChar.extend({
|
||||
|
||||
@@ -216,11 +123,6 @@ var FieldEmbedURLViewer = fields.FieldChar.extend({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
field_registry
|
||||
.add('mrp_time_counter', TimeCounter)
|
||||
.add('embed_viewer', FieldEmbedURLViewer);
|
||||
|
||||
fieldUtils.format.mrp_time_counter = fieldUtils.format.float_time;
|
||||
field_registry.add('embed_viewer', FieldEmbedURLViewer);
|
||||
|
||||
export default FieldEmbedURLViewer;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { formatFloatTime } from "@web/views/fields/formatters";
|
||||
|
||||
const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl;
|
||||
|
||||
export class MrpTimer extends Component {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.state = useState({
|
||||
duration:
|
||||
this.props.duration !== undefined
|
||||
? this.props.duration
|
||||
: this.props.record.data.duration,
|
||||
});
|
||||
|
||||
const newLocal = this;
|
||||
this.ongoing =
|
||||
this.props.ongoing !== undefined
|
||||
? newLocal.props.ongoing
|
||||
: this.props.record.data.is_user_working;
|
||||
|
||||
onWillStart(() => this._runTimer());
|
||||
onWillUpdateProps((nextProps) => {
|
||||
this.ongoing = nextProps.ongoing;
|
||||
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 });
|
||||
}
|
||||
|
||||
_runTimer() {
|
||||
if (this.ongoing) {
|
||||
this.timer = setTimeout(() => {
|
||||
this.state.duration += 1 / 60;
|
||||
this._runTimer();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MrpTimer.supportedTypes = ["float"];
|
||||
MrpTimer.template = "mrp.MrpTimer";
|
||||
|
||||
registry.category("fields").add("mrp_timer", MrpTimer);
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="mrp.MrpTimer" owl="1">
|
||||
<span><t t-esc="duration"/></span>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -28,38 +28,6 @@ QUnit.module('mrp', {
|
||||
},
|
||||
}, function () {
|
||||
|
||||
QUnit.test("mrp_time_counter: basic rendering", async function (assert) {
|
||||
assert.expect(2);
|
||||
var data = {
|
||||
foo: {
|
||||
fields: { duration: { string: "Duration", type: "float" } },
|
||||
records: [{id: 1, duration:150.5}]
|
||||
},
|
||||
};
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
model: 'foo',
|
||||
data: data,
|
||||
res_id: 1,
|
||||
arch:
|
||||
'<form>' +
|
||||
'<field name="duration" widget="mrp_time_counter"/>' +
|
||||
'</form>',
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'search_read' && args.model === 'mrp.workcenter.productivity') {
|
||||
assert.ok(true, "the widget should fetch the mrp.workcenter.productivity");
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_field_widget[name="duration"]').text(), "150:30",
|
||||
"the timer should be correctly set");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test("embed_viewer rendering in form view", async function (assert) {
|
||||
assert.expect(8);
|
||||
var data = {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
QUnit.module("Mrp", (hooks) => {
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
serverData = {
|
||||
models: {
|
||||
foo: {
|
||||
fields: {
|
||||
duration: { string: "Duration", type: "float" },
|
||||
},
|
||||
records: [{ id: 1, duration: 150.5 }],
|
||||
},
|
||||
},
|
||||
};
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.module("MrpTimer");
|
||||
|
||||
QUnit.test("ensure the rendering is based on minutes and seconds", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
serverData,
|
||||
resModel: "foo",
|
||||
resId: 1,
|
||||
arch: '<form><field name="duration" widget="mrp_timer"/></form>',
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_mrp_timer").textContent,
|
||||
"02:30:30",
|
||||
"should contain hours and be correctly set base on minutes seconds"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -84,7 +84,7 @@
|
||||
<field name="date_start" optional="hide" readonly="1"/>
|
||||
<field name="date_finished" optional="hide" readonly="1"/>
|
||||
<field name="duration_expected" widget="float_time" sum="expected duration"/>
|
||||
<field name="duration" widget="mrp_time_counter"
|
||||
<field name="duration" widget="mrp_timer"
|
||||
attrs="{'invisible': [('production_state','=', 'draft')], 'readonly': [('is_user_working', '=', True)]}" sum="real duration"/>
|
||||
<field name="state" widget="badge" decoration-warning="state == 'progress'" decoration-success="state == 'done'" decoration-danger="state == 'cancel'" decoration-info="state not in ('progress', 'done', 'cancel')"
|
||||
attrs="{'invisible': [('production_state', '=', 'draft')], 'column_invisible': [('parent.state', '=', 'draft')]}"/>
|
||||
|
||||
Reference in New Issue
Block a user