diff --git a/project_task_timer/__manifest__.py b/project_task_timer/__manifest__.py index 506f68fc2..f06d94036 100644 --- a/project_task_timer/__manifest__.py +++ b/project_task_timer/__manifest__.py @@ -26,14 +26,13 @@ 'author': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions', 'website': "http://www.cybrosys.com", - 'depends': ['base', 'project', 'hr_timesheet'], + 'depends': ['base', 'project', 'hr_timesheet','web'], 'data': [ 'views/project_task_timer_view.xml', ], '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 871ad13b5..d44c25048 100644 --- a/project_task_timer/models/project_task_timer.py +++ b/project_task_timer/models/project_task_timer.py @@ -26,7 +26,8 @@ class ProjectTaskTimeSheet(models.Model): date_start = fields.Datetime(string='Start Date') date_end = fields.Datetime(string='End Date', readonly=1) - timer_duration = fields.Float(invisible=1, string='Time Duration (Minutes)=') + timer_duration = fields.Float(invisible=1, + string='Time Duration (Minutes)=') class ProjectTaskTimer(models.Model): @@ -40,12 +41,15 @@ class ProjectTaskTimer(models.Model): 'Real Duration', compute='_compute_duration', store=True) def _compute_duration(self): + """Compute Duration""" self def _compute_is_user_working(self): """ Checks whether the current user is working """ for order in self: - if order.timesheet_ids.filtered(lambda x: (x.user_id.id == self.env.user.id) and (not x.date_end)): + if order.timesheet_ids.filtered( + lambda x: (x.user_id.id == self.env.user.id) and ( + not x.date_end)): order.is_user_working = True else: order.is_user_working = False @@ -69,23 +73,15 @@ 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): - 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) - - 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 + time_line.write({'date_end': fields.Datetime.now()}) + if time_line.date_start and time_line.date_end: + diff = fields.Datetime.from_string( + time_line.date_end) - fields.Datetime.from_string( + time_line.date_start).replace(microsecond=0) + 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 diff --git a/project_task_timer/static/src/js/timer.js b/project_task_timer/static/src/js/timer.js index 19d4675a8..035e65ee9 100644 --- a/project_task_timer/static/src/js/timer.js +++ b/project_task_timer/static/src/js/timer.js @@ -1,86 +1,82 @@ -/** @odoo-module **/ +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'); -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"; +var _t = core._t; -const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl; +// $(document).on('click','#timer', function(){ +// if ($(this).hasClass('btn-secondary')) +// { $(this).removeClass('btn-secondary'); +// $(this).addClass('btn-primary'); +// } +// }); -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}`; -} +/** + * Custom field type for displaying a time counter based on data from the account.analytic.line model. + * Inherits from the AbstractField class. + */ -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), - }); +var TimeCounter = AbstractField.extend({ - 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(); + 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); + }); } }); - 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)); - } + 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)); + }, - get durationFormatted() { - return formatMinutes(this.state.duration); - } + _render: function () { + this._startTimeCounter(); + }, - _runTimer() { - this.timer = setTimeout(() => { - if (this.ongoing) { - this.state.duration += 1 / 60; - this._runTimer(); - } - }, 1000); - } -} + /** + * Starts a timer to update the field every second if the user is working. + * Increments the duration by one second each time the timer runs. + * Updates the field with the new duration in HH:mm:ss format. + */ + _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); +}); -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 deleted file mode 100644 index 469fe56b8..000000000 --- a/project_task_timer/static/src/xml/timer.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/project_task_timer/views/project_task_timer_view.xml b/project_task_timer/views/project_task_timer_view.xml index bf023cdfa..a5ce4692e 100644 --- a/project_task_timer/views/project_task_timer_view.xml +++ b/project_task_timer/views/project_task_timer_view.xml @@ -26,6 +26,7 @@ project.task + @@ -36,7 +37,7 @@