From 5e0fb6e49e452fb9efa65f2685059c7d1ab7f250 Mon Sep 17 00:00:00 2001 From: AjmalCybro Date: Thu, 18 May 2023 10:51:24 +0530 Subject: [PATCH] May 18 : [UPDT] Bug Fixed 'project_task_timer' --- project_task_timer/__manifest__.py | 1 + .../models/project_task_timer.py | 26 ++-- project_task_timer/static/src/js/timer.js | 138 ++++++++++-------- project_task_timer/static/src/xml/timer.xml | 7 + .../views/project_task_timer_view.xml | 2 +- 5 files changed, 103 insertions(+), 71 deletions(-) create mode 100644 project_task_timer/static/src/xml/timer.xml diff --git a/project_task_timer/__manifest__.py b/project_task_timer/__manifest__.py index 5561083b0..506f68fc2 100644 --- a/project_task_timer/__manifest__.py +++ b/project_task_timer/__manifest__.py @@ -33,6 +33,7 @@ 'assets': { 'web.assets_backend': [ 'project_task_timer/static/src/js/timer.js', + 'project_task_timer/static/src/xml/timer.xml', ]}, 'images': ['static/description/banner.png'], 'license': 'AGPL-3', diff --git a/project_task_timer/models/project_task_timer.py b/project_task_timer/models/project_task_timer.py index 397b93c90..871ad13b5 100644 --- a/project_task_timer/models/project_task_timer.py +++ b/project_task_timer/models/project_task_timer.py @@ -69,15 +69,23 @@ class ProjectTaskTimer(models.Model): time_line_obj = self.env['account.analytic.line'] domain = [('task_id', 'in', self.ids), ('date_end', '=', False)] for time_line in time_line_obj.search(domain): - time_line.write({'date_end': fields.Datetime.now()}) - if time_line.date_end: - diff = fields.Datetime.from_string(time_line.date_end) - fields.Datetime.from_string(time_line.date_start).replace(microsecond=0) + if time_line.date_start: + time_line.write({'date_end': fields.Datetime.now()}) + diff = fields.Datetime.from_string(time_line.date_end) - fields.Datetime.from_string(time_line.date_start) time_line.timer_duration = round(diff.total_seconds() / 60.0, 2) time_line.unit_amount = round(diff.total_seconds() / (60.0 * 60.0), 2) - else: - time_line.unit_amount = 0.0 - time_line.timer_duration = 0.0 - - - + def get_working_duration(self): + """Get the additional duration for 'open times' + i.e. productivity lines with no date_end.""" + self.ensure_one() + duration = 0 + for time in \ + self.timesheet_ids.filtered(lambda time: not time.date_end): + if type(time.date_start) != datetime: + time.date_start = datetime.now() + duration = 0 + else: + duration += \ + (datetime.now() - time.date_start).total_seconds() / 60 + return duration diff --git a/project_task_timer/static/src/js/timer.js b/project_task_timer/static/src/js/timer.js index 263ca45de..19d4675a8 100644 --- a/project_task_timer/static/src/js/timer.js +++ b/project_task_timer/static/src/js/timer.js @@ -1,70 +1,86 @@ -odoo.define('project_task_timer.timer', function (require) { -"use strict"; -var AbstractField = require('web.AbstractField'); -var core = require('web.core'); -var field_registry = require('web.field_registry'); -var time = require('web.time'); -var FieldManagerMixin = require('web.FieldManagerMixin'); +/** @odoo-module **/ -var _t = core._t; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +import { parseFloatTime } from "@web/views/fields/parsers"; +import { useInputField } from "@web/views/fields/input_field_hook"; -// $(document).on('click','#timer', function(){ -// if ($(this).hasClass('btn-secondary')) -// { $(this).removeClass('btn-secondary'); -// $(this).addClass('btn-primary'); -// } -// }); +const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl; -var TimeCounter = AbstractField.extend({ +function formatMinutes(value) { + if (value === false) { + return ""; + } + const isNegative = value < 0; + if (isNegative) { + value = Math.abs(value); + } + let min = Math.floor(value); + let sec = Math.floor((value % 1) * 60); + sec = `${sec}`.padStart(2, "0"); + min = `${min}`.padStart(2, "0"); + return `${isNegative ? "-" : ""}${min}:${sec}`; +} - willStart: function () { - var self = this; - var def = this._rpc({ - model: 'account.analytic.line', - method: 'search_read', - domain: [['task_id', '=', this.res_id], ['user_id', '=', self.record.context['uid']]], - }).then(function (result) { - if (self.mode === 'readonly') { - var currentDate = new Date(); - self.duration = 0; - _.each(result, function (data) { - self.duration += data.date_end ? - self._getDateDifference(data.date_start, data.date_end): - self._getDateDifference(time.auto_str_to_date(data.date_start), currentDate); - }); +export class TaskTimer extends Component { + setup() { + this.orm = useService('orm'); + this.state = useState({ + // duration is expected to be given in minutes + duration: + this.props.value !== undefined ? this.props.value : this.props.record.data.duration, + }); + useInputField({ + getValue: () => this.durationFormatted, + refName: "numpadDecimal", + parse: (v) => parseFloatTime(v), + }); + + this.ongoing = + this.props.ongoing !== undefined + ? this.props.ongoing + : this.props.record.data.is_user_working; + + onWillStart(async () => { + if(this.props.ongoing === undefined && !this.props.record.model.useSampleModel && this.props.record.data.task_timer) { + const additionalDuration = await this.orm.call('project.task', 'get_working_duration', [this.props.record.resId]); + this.state.duration += additionalDuration; + } + if (this.ongoing) { + this._runTimer(); } }); - return $.when(this._super.apply(this, arguments), def); - }, - destroy: function () { - this._super.apply(this, arguments); - clearTimeout(this.timer); - }, - isSet: function () { - return true; - }, - _getDateDifference: function (dateStart, dateEnd) { - return moment(dateEnd).diff(moment(dateStart)); - }, + onWillUpdateProps((nextProps) => { + 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.state.duration = nextProps.value; + this._runTimer(); + } + }); + onWillDestroy(() => clearTimeout(this.timer)); + } - _render: function () { - this._startTimeCounter(); - }, - _startTimeCounter: function () { - var self = this; - clearTimeout(this.timer); - if (this.record.data.is_user_working) { - this.timer = setTimeout(function () { - self.duration += 1000; - self._startTimeCounter(); - }, 1000); - } else { - clearTimeout(this.timer); - } - this.$el.html($('' + moment.utc(this.duration).format("HH:mm:ss") + '')); - }, -}); -field_registry.add('timesheet_uoms', TimeCounter); -}); + get durationFormatted() { + return formatMinutes(this.state.duration); + } + + _runTimer() { + this.timer = setTimeout(() => { + if (this.ongoing) { + this.state.duration += 1 / 60; + this._runTimer(); + } + }, 1000); + } +} +TaskTimer.supportedTypes = ["float"]; +TaskTimer.template = "TaskTimerTemplate"; +registry.category("fields").add("task_timer", TaskTimer); +registry.category("formatters").add("task_timer", formatMinutes); \ No newline at end of file diff --git a/project_task_timer/static/src/xml/timer.xml b/project_task_timer/static/src/xml/timer.xml new file mode 100644 index 000000000..469fe56b8 --- /dev/null +++ b/project_task_timer/static/src/xml/timer.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/project_task_timer/views/project_task_timer_view.xml b/project_task_timer/views/project_task_timer_view.xml index c01021c8e..bf023cdfa 100644 --- a/project_task_timer/views/project_task_timer_view.xml +++ b/project_task_timer/views/project_task_timer_view.xml @@ -36,7 +36,7 @@