diff --git a/project_task_timer/__init__.py b/project_task_timer/__init__.py new file mode 100644 index 000000000..59493eaa8 --- /dev/null +++ b/project_task_timer/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import models diff --git a/project_task_timer/__manifest__.py b/project_task_timer/__manifest__.py new file mode 100644 index 000000000..c074dea46 --- /dev/null +++ b/project_task_timer/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'Project Task Timer', + 'version': '10.0.1.0', + 'summary': """Task Timer With Start & Stop""", + 'description': """"This module helps you to track time sheet in project automatically.""", + 'category': 'Project', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': "http://www.cybrosys.com", + 'depends': ['base', 'project', 'hr_timesheet'], + 'data': [ + 'views/project_task_timer_view.xml', + 'views/project_timer_static.xml', + ], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'demo': [], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/project_task_timer/models/__init__.py b/project_task_timer/models/__init__.py new file mode 100644 index 000000000..f4dfb4775 --- /dev/null +++ b/project_task_timer/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import project_task_timer diff --git a/project_task_timer/models/project_task_timer.py b/project_task_timer/models/project_task_timer.py new file mode 100644 index 000000000..b3f081ab4 --- /dev/null +++ b/project_task_timer/models/project_task_timer.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from datetime import datetime +from odoo import models, fields, api + + +class ProjectTaskTimeSheet(models.Model): + _inherit = 'account.analytic.line' + + date_start = fields.Datetime(string='Start Date') + date_end = fields.Datetime(string='End Date', readonly=1) + + +class ProjectTaskTimer(models.Model): + _inherit = 'project.task' + + 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)): + order.is_user_working = True + else: + order.is_user_working = False + + @api.multi + @api.depends('timesheet_ids.unit_amount') + def _compute_duration(self): + self.duration = 0 + for each in self: + each.duration = sum(each.timesheet_ids.mapped('unit_amount')) + + @api.multi + def toggle_start(self): + for record in self: + record.task_timer = not record.task_timer + if self.task_timer: + self.write({'is_user_working': True}) + time_line = self.env['account.analytic.line'] + for time_sheet in self: + time_line.create({ + 'name': self.env.user.name + ': ' + time_sheet.name, + 'task_id': time_sheet.id, + 'user_id': self.env.user.id, + 'project_id': time_sheet.project_id.id, + 'date_start': datetime.now(), + }) + else: + self.write({'is_user_working': False}) + 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) + time_line.unit_amount = round(diff.total_seconds() / 60.0, 2) + else: + time_line.unit_amount = 0.0 + + task_timer = fields.Boolean() + is_user_working = fields.Boolean( + 'Is Current User Working', compute='_compute_is_user_working', + help="Technical field indicating whether the current user is working. ") + duration = fields.Float( + 'Real Duration', compute='_compute_duration', + readonly=True, store=True) + + + + + diff --git a/project_task_timer/static/description/banner.jpg b/project_task_timer/static/description/banner.jpg new file mode 100644 index 000000000..1ce48898d Binary files /dev/null and b/project_task_timer/static/description/banner.jpg differ diff --git a/project_task_timer/static/description/cybro_logo.png b/project_task_timer/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/project_task_timer/static/description/cybro_logo.png differ diff --git a/project_task_timer/static/description/icon.png b/project_task_timer/static/description/icon.png new file mode 100644 index 000000000..df58193f0 Binary files /dev/null and b/project_task_timer/static/description/icon.png differ diff --git a/project_task_timer/static/description/index.html b/project_task_timer/static/description/index.html new file mode 100644 index 000000000..4fd99305a --- /dev/null +++ b/project_task_timer/static/description/index.html @@ -0,0 +1,87 @@ +
+
+

Project Task Timer

+

Task Timer with Start & Stop

+

Author : Cybrosys Techno Solutions , www.cybrosys.com

+
+

Features:

+
    +
  •    Timer in Task.
  • +
  •    Automatic Time sheet Calculation.
  • +
+
+

+ You have a smart button to start & stop your task. When you start your task it will automatically makes + a time sheet entry for that task with starting time. When you toggle it to pause it's end date will be update + and duration will calculate automatically. +

+
+
+ +
+
+

Timer in Task

+
+
+

+ Project -> Search -> Task
+ Here you can a toggle button to start and stop your task. +

+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+

Automatic Time sheet Calculation

+
+
+

+ Here you can see the Automatic time sheet entries. +

+
+
+
+ +
+
+
+
+
+ +
+

Need Any Help?

+ +
diff --git a/project_task_timer/static/description/timer1.png b/project_task_timer/static/description/timer1.png new file mode 100644 index 000000000..9f1158765 Binary files /dev/null and b/project_task_timer/static/description/timer1.png differ diff --git a/project_task_timer/static/description/timer2.png b/project_task_timer/static/description/timer2.png new file mode 100644 index 000000000..82f0e0f63 Binary files /dev/null and b/project_task_timer/static/description/timer2.png differ diff --git a/project_task_timer/static/description/timer3.png b/project_task_timer/static/description/timer3.png new file mode 100644 index 000000000..9bdba03b5 Binary files /dev/null and b/project_task_timer/static/description/timer3.png differ diff --git a/project_task_timer/static/src/js/timer.js b/project_task_timer/static/src/js/timer.js new file mode 100644 index 000000000..b7fb2b268 --- /dev/null +++ b/project_task_timer/static/src/js/timer.js @@ -0,0 +1,57 @@ +odoo.define('timer_widget.timer', function (require) { +"use strict"; + +var core = require('web.core'); +var common = require('web.form_common'); +var Model = require('web.Model'); +var time = require('web.time'); +var utils = require('web.utils'); + +var _t = core._t; + +var TimeCounter = common.AbstractField.extend(common.ReinitializeFieldMixin, { + start: function() { + this._super(); + var self = this; + this.field_manager.on("view_content_has_changed", this, function () { + self.render_value(); + }); + }, + start_time_counter: function(){ + var self = this; + clearTimeout(this.timer); + if (this.field_manager.datarecord.is_user_working) { + this.duration += 1000; + this.timer = setTimeout(function() { + self.start_time_counter(); + }, 1000); + } else { + clearTimeout(this.timer); + } + this.$el.html($('' + moment.utc(this.duration).format("HH:mm:ss") + '')); + }, + render_value: function() { + this._super.apply(this, arguments); + var self = this; + this.duration; + var productivity_domain = [['task_id', '=', this.field_manager.datarecord.id], ['user_id', '=', self.session.uid]]; + new Model('account.analytic.line').call('search_read', [productivity_domain, []]).then(function(result) { + if (self.get("effective_readonly")) { + self.$el.removeClass('o_form_field_empty'); + var current_date = new Date(); + self.duration = 0; + _.each(result, function(data) { + self.duration += data.date_end ? self.get_date_difference(data.date_start, data.date_end) : self.get_date_difference(time.auto_str_to_date(data.date_start), current_date); + }); + self.start_time_counter(); + } + }); + }, + get_date_difference: function(date_start, date_deadline) { + var difference = moment(date_deadline).diff(moment(date_start)); + return moment.duration(difference); + }, +}); + +core.form_widget_registry.add('time_counter', TimeCounter); +}); diff --git a/project_task_timer/views/project_task_timer_view.xml b/project_task_timer/views/project_task_timer_view.xml new file mode 100644 index 000000000..a4d24c3a8 --- /dev/null +++ b/project_task_timer/views/project_task_timer_view.xml @@ -0,0 +1,45 @@ + + + + + project task timer + project.task + + +
+ +
+ + + + +
+ + + project task timer1 + project.task + + + + + + + + +
+
\ No newline at end of file diff --git a/project_task_timer/views/project_timer_static.xml b/project_task_timer/views/project_timer_static.xml new file mode 100644 index 000000000..6c3566376 --- /dev/null +++ b/project_task_timer/views/project_timer_static.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file