diff --git a/automatic_project_task_timer/README.rst b/automatic_project_task_timer/README.rst new file mode 100644 index 000000000..36d08b992 --- /dev/null +++ b/automatic_project_task_timer/README.rst @@ -0,0 +1,51 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +Automatic Project Task Timer +============================ +App for running the timer automatically for the task comes in In Progress stage. + +Configuration +============= +* For configuring the timer, Go to Users --> Set the user group as Administrator + for Projects then, + + Projects --> Configuration --> Timer Configuration menu to configure the + project and stage. + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +GNU AFFERO GENERAL PUBLIC LICENSE v3.0 (AGPL-3) +(https://www.gnu.org/licenses/agpl-3.0-standalone.html) + +Credits +------- +* Developers: (V17) Mohammed Irfan T, Contact: odoo@cybrosys.com +* Developers: (V16) Prathyunnan R, Contact: odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ diff --git a/automatic_project_task_timer/__init__.py b/automatic_project_task_timer/__init__.py new file mode 100644 index 000000000..23fbb85a8 --- /dev/null +++ b/automatic_project_task_timer/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import models diff --git a/automatic_project_task_timer/__manifest__.py b/automatic_project_task_timer/__manifest__.py new file mode 100644 index 000000000..060500560 --- /dev/null +++ b/automatic_project_task_timer/__manifest__.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +{ + 'name': 'Automatic Project Task Timer', + 'version': '17.0.1.0.0', + 'category': 'Project', + 'summary': 'Automatic Running Timer for Project Tasks', + 'description': "This module helps you to track time sheet in project " + "using a real timer, it's starts when task is in " + "configured stage and stops when its moves to any other " + "stage and the timesheet will be recorded.", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['hr_timesheet'], + 'data': [ + 'security/ir.model.access.csv', + 'views/project_task_views.xml', + 'views/res_config_settings_views.xml', + 'views/timer_configuration_views.xml' + ], + 'assets': { + 'web.assets_backend': [ + 'automatic_project_task_timer/static/src/js/task_timer.js', + 'automatic_project_task_timer/static/src/js/form_open.js', + 'automatic_project_task_timer/static/src/xml/task_timer_templates.xml', + ]}, + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/automatic_project_task_timer/doc/RELEASE_NOTES.md b/automatic_project_task_timer/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..8a1c27553 --- /dev/null +++ b/automatic_project_task_timer/doc/RELEASE_NOTES.md @@ -0,0 +1,5 @@ +## Module +#### 08.07.2024 +#### Version 17.0.1.0.0 +#### ADD +- Initial commit for Automatic Project Task Timer diff --git a/automatic_project_task_timer/models/__init__.py b/automatic_project_task_timer/models/__init__.py new file mode 100644 index 000000000..d75723967 --- /dev/null +++ b/automatic_project_task_timer/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import account_analytic_line +from . import project_task +from . import res_config_settings +from . import timer_configuration diff --git a/automatic_project_task_timer/models/account_analytic_line.py b/automatic_project_task_timer/models/account_analytic_line.py new file mode 100644 index 000000000..24942cf60 --- /dev/null +++ b/automatic_project_task_timer/models/account_analytic_line.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class AccountAnalyticLine(models.Model): + """inherited the 'account.analytic.line' for showing the time records.""" + _inherit = 'account.analytic.line' + + date_start = fields.Datetime(string='Start Date', help='Shows the ' + 'starting time of ' + 'the timer') + date_end = fields.Datetime(string='End Date', help='Shows ' + 'the ending' + ' time of ' + 'the timer') + timer_duration = fields.Float(string='Time Duration(Minutes)', + help='Shows the real time ') diff --git a/automatic_project_task_timer/models/project_task.py b/automatic_project_task_timer/models/project_task.py new file mode 100644 index 000000000..ba1b0b4ef --- /dev/null +++ b/automatic_project_task_timer/models/project_task.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from datetime import datetime +from odoo import api, fields, models + + +class Task(models.Model): + """inherited the 'project.task' for running the timer """ + _inherit = 'project.task' + + task_timer = fields.Boolean(string='Timer', default=False, + help='Activated when task configured stage') + is_user_working = fields.Boolean(string='Is Current User Working', + compute='_compute_is_user_working', + help="Technical field indicating whether " + "the current user is working. ") + duration = fields.Float(string='Real Duration', store=True, copy=False, + readonly=False, help='Shows the duration') + is_status_stage = fields.Boolean(string='Stage Status', + help='To set the status of task at the ' + 'initial time.') + check_stage = fields.Integer(string='Stage', + compute='_compute_check_stage', + help='To check the stage whether it is ' + 'configured or not') + + def _compute_check_stage(self): + """To check the stage whether it is configured or not, for that + assigning the configured stage id to this field.""" + for rec in self: + rec.check_stage = self.env['timer.configuration'].search( + [('project_id.id', '=', rec.project_id.id)]).stage_id.id + + @api.constrains('stage_id') + def _task_timer(self): + """Checks the status of timer setting and + toggle the task timer boolean to active """ + self.write({ + 'is_status_stage': False + }) + timer_setting = self.env['ir.config_parameter'].sudo().get_param( + 'automatic_project_task_timer.timer_setting') + if timer_setting: + for rec in self.env['timer.configuration'].search([]): + if self.project_id == rec.project_id: + if self.stage_id.id == rec.stage_id.id: + self.write({'task_timer': True}) + else: + self.write({'task_timer': False}) + + 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.model + @api.constrains('task_timer') + def toggle_start(self): + """The time sheet record will be created + by checking all the conditions """ + time_line_obj = self.env['account.analytic.line'] + for rec in self: + if rec.task_timer is True: + rec.write({'is_user_working': True}) + for time_sheet in rec: + time_line_obj.create({ + 'name': '%s : %s' % (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: + rec.write({'is_user_working': False}) + for time_line in time_line_obj.search( + [('task_id', 'in', self.ids), + ('date_end', '=', False)]): + time_line.write({'date_end': fields.Datetime.now()}) + if time_line.date_start: + if time_line.date_end: + diff = fields.Datetime.from_string( + time_line.date_end) \ + - fields.Datetime.from_string( + time_line.date_start).replace( + second=0, 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 + else: + time_line.write({'date_start': 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( + second=0, 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 + + 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/automatic_project_task_timer/models/res_config_settings.py b/automatic_project_task_timer/models/res_config_settings.py new file mode 100644 index 000000000..07d1fa3e5 --- /dev/null +++ b/automatic_project_task_timer/models/res_config_settings.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + """inherited the 'res.config.settings' + for activating timer in project module.""" + _inherit = 'res.config.settings' + + timer_setting = fields.Boolean( + string='Task Timer', + config_parameter='automatic_project_task_timer.timer_setting', + help='Enable to activate the timer') diff --git a/automatic_project_task_timer/models/timer_configuration.py b/automatic_project_task_timer/models/timer_configuration.py new file mode 100644 index 000000000..d1a88f14d --- /dev/null +++ b/automatic_project_task_timer/models/timer_configuration.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Irfan T(odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models + + +class TimerConfiguration(models.Model): + """Timer configuration model for configure the automatic timer + stage to activate the timer, Each project have different stages, + based on the configured stage for each project the timer will be runs.""" + _name = 'timer.configuration' + _description = 'Timer Configuration' + + project_id = fields.Many2one('project.project', string='Project', + help='Configure the project to activate the ' + 'timer') + stage_ids = fields.Many2many('project.task.type', + string='Stages', + help='To set the domain for stages') + stage_id = fields.Many2one('project.task.type', string='Stage', + help='Set the stage to activate the timer', + domain="[('id', 'in', stage_ids)]", + required=True) + + @api.onchange('project_id') + def _onchange_project_id(self): + """To set the domain for stage_id field to select the stages + from the stages of the selected project""" + data = [] + for rec in self.env['project.task.type'].search([]): + if self.project_id.id in rec.project_ids.ids: + data.append(rec.id) + self.stage_ids = data + + @api.model + def create(self, vals): + """To set the status stage for all the tasks in the corresponding + project, so that the warning message will pop-ups when the form + opens. For that supering the ORM Create method to get the corresponding + project. """ + projects = self.env['project.project'].sudo().browse(vals.get( + 'project_id')) + tasks = self.env['project.task'].search([('project_id', '=' ,projects.id)]) + for records in tasks: + if records.stage_id.id == vals.get('stage_id'): + records.write({ + 'is_status_stage': True + }) + else: + records.write({ + 'is_status_stage': False + }) + res = super(TimerConfiguration, self).create(vals) + return res diff --git a/automatic_project_task_timer/security/ir.model.access.csv b/automatic_project_task_timer/security/ir.model.access.csv new file mode 100644 index 000000000..f6a7ffa10 --- /dev/null +++ b/automatic_project_task_timer/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_timer_configuration_manager,access.timer.configuration.manager,model_timer_configuration,project.group_project_manager,1,1,1,1 +access_timer_configuration_user,access.timer.configuration.user,model_timer_configuration,project.group_project_user,0,0,1,0 diff --git a/automatic_project_task_timer/static/description/assets/icons/check.png b/automatic_project_task_timer/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/check.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/chevron.png b/automatic_project_task_timer/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/chevron.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/cogs.png b/automatic_project_task_timer/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/cogs.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/consultation.png b/automatic_project_task_timer/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/consultation.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/ecom-black.png b/automatic_project_task_timer/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/ecom-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/education-black.png b/automatic_project_task_timer/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/education-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/hotel-black.png b/automatic_project_task_timer/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/hotel-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/license.png b/automatic_project_task_timer/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/license.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/lifebuoy.png b/automatic_project_task_timer/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/lifebuoy.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/manufacturing-black.png b/automatic_project_task_timer/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/manufacturing-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/pos-black.png b/automatic_project_task_timer/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/pos-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/puzzle.png b/automatic_project_task_timer/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/puzzle.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/restaurant-black.png b/automatic_project_task_timer/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/restaurant-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/service-black.png b/automatic_project_task_timer/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/service-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/trading-black.png b/automatic_project_task_timer/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/trading-black.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/training.png b/automatic_project_task_timer/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/training.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/update.png b/automatic_project_task_timer/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/update.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/user.png b/automatic_project_task_timer/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/user.png differ diff --git a/automatic_project_task_timer/static/description/assets/icons/wrench.png b/automatic_project_task_timer/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/icons/wrench.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/Cybrosys R.png b/automatic_project_task_timer/static/description/assets/misc/Cybrosys R.png new file mode 100644 index 000000000..da4058087 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/Cybrosys R.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/categories.png b/automatic_project_task_timer/static/description/assets/misc/categories.png new file mode 100644 index 000000000..bedf1e0b1 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/categories.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/check-box.png b/automatic_project_task_timer/static/description/assets/misc/check-box.png new file mode 100644 index 000000000..42caf24b9 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/check-box.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/compass.png b/automatic_project_task_timer/static/description/assets/misc/compass.png new file mode 100644 index 000000000..d5fed8faa Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/compass.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/corporate.png b/automatic_project_task_timer/static/description/assets/misc/corporate.png new file mode 100644 index 000000000..2eb13edbf Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/corporate.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/customer-support.png b/automatic_project_task_timer/static/description/assets/misc/customer-support.png new file mode 100644 index 000000000..79efc72ed Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/customer-support.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/cybrosys-logo.png b/automatic_project_task_timer/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 000000000..cc3cc0ccf Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/cybrosys-logo.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/features.png b/automatic_project_task_timer/static/description/assets/misc/features.png new file mode 100644 index 000000000..b41769f77 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/features.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/logo.png b/automatic_project_task_timer/static/description/assets/misc/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/logo.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/phone.svg b/automatic_project_task_timer/static/description/assets/misc/phone.svg new file mode 100644 index 000000000..b7bd7f251 --- /dev/null +++ b/automatic_project_task_timer/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/automatic_project_task_timer/static/description/assets/misc/pictures.png b/automatic_project_task_timer/static/description/assets/misc/pictures.png new file mode 100644 index 000000000..56d255fe9 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/pictures.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/pie-chart.png b/automatic_project_task_timer/static/description/assets/misc/pie-chart.png new file mode 100644 index 000000000..426e05244 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/pie-chart.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/right-arrow.png b/automatic_project_task_timer/static/description/assets/misc/right-arrow.png new file mode 100644 index 000000000..730984a06 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/right-arrow.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/star.png b/automatic_project_task_timer/static/description/assets/misc/star.png new file mode 100644 index 000000000..2eb9ab29f Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/star.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/support (1) 1.svg b/automatic_project_task_timer/static/description/assets/misc/support (1) 1.svg new file mode 100644 index 000000000..7d37a8f30 --- /dev/null +++ b/automatic_project_task_timer/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/automatic_project_task_timer/static/description/assets/misc/support-email.svg b/automatic_project_task_timer/static/description/assets/misc/support-email.svg new file mode 100644 index 000000000..eb70370d6 --- /dev/null +++ b/automatic_project_task_timer/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/automatic_project_task_timer/static/description/assets/misc/support.png b/automatic_project_task_timer/static/description/assets/misc/support.png new file mode 100644 index 000000000..4f18b8b82 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/support.png differ diff --git a/automatic_project_task_timer/static/description/assets/misc/whatsapp 1.svg b/automatic_project_task_timer/static/description/assets/misc/whatsapp 1.svg new file mode 100644 index 000000000..0bfaf8fc6 --- /dev/null +++ b/automatic_project_task_timer/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/automatic_project_task_timer/static/description/assets/misc/whatsapp.png b/automatic_project_task_timer/static/description/assets/misc/whatsapp.png new file mode 100644 index 000000000..d513a5356 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/misc/whatsapp.png differ diff --git a/automatic_project_task_timer/static/description/assets/modules/1.jpg b/automatic_project_task_timer/static/description/assets/modules/1.jpg new file mode 100644 index 000000000..0edf328e5 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/1.jpg differ diff --git a/automatic_project_task_timer/static/description/assets/modules/2.gif b/automatic_project_task_timer/static/description/assets/modules/2.gif new file mode 100644 index 000000000..8ac32db03 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/2.gif differ diff --git a/automatic_project_task_timer/static/description/assets/modules/3.jpg b/automatic_project_task_timer/static/description/assets/modules/3.jpg new file mode 100644 index 000000000..677f72279 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/3.jpg differ diff --git a/automatic_project_task_timer/static/description/assets/modules/4.jpg b/automatic_project_task_timer/static/description/assets/modules/4.jpg new file mode 100644 index 000000000..1e087eed6 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/4.jpg differ diff --git a/automatic_project_task_timer/static/description/assets/modules/5.png b/automatic_project_task_timer/static/description/assets/modules/5.png new file mode 100644 index 000000000..3bedf7981 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/5.png differ diff --git a/automatic_project_task_timer/static/description/assets/modules/6.jpg b/automatic_project_task_timer/static/description/assets/modules/6.jpg new file mode 100644 index 000000000..482309000 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/modules/6.jpg differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/1.png b/automatic_project_task_timer/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..a7941bbfa Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/1.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/2.png b/automatic_project_task_timer/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..1b6a18a4b Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/2.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/3.png b/automatic_project_task_timer/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..5d405a6ff Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/3.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/4.png b/automatic_project_task_timer/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..73772ff0c Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/4.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/5.png b/automatic_project_task_timer/static/description/assets/screenshots/5.png new file mode 100644 index 000000000..7cab81455 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/5.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/6.png b/automatic_project_task_timer/static/description/assets/screenshots/6.png new file mode 100644 index 000000000..a345503d1 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/6.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/7.png b/automatic_project_task_timer/static/description/assets/screenshots/7.png new file mode 100644 index 000000000..f46012383 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/7.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/8.png b/automatic_project_task_timer/static/description/assets/screenshots/8.png new file mode 100644 index 000000000..0d80850df Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/8.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/9.png b/automatic_project_task_timer/static/description/assets/screenshots/9.png new file mode 100644 index 000000000..cf8b304c6 Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/9.png differ diff --git a/automatic_project_task_timer/static/description/assets/screenshots/hero.gif b/automatic_project_task_timer/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..c401e464b Binary files /dev/null and b/automatic_project_task_timer/static/description/assets/screenshots/hero.gif differ diff --git a/automatic_project_task_timer/static/description/banner.jpg b/automatic_project_task_timer/static/description/banner.jpg new file mode 100644 index 000000000..da0c9deb7 Binary files /dev/null and b/automatic_project_task_timer/static/description/banner.jpg differ diff --git a/automatic_project_task_timer/static/description/icon.png b/automatic_project_task_timer/static/description/icon.png new file mode 100644 index 000000000..7ba39bfd3 Binary files /dev/null and b/automatic_project_task_timer/static/description/icon.png differ diff --git a/automatic_project_task_timer/static/description/index.html b/automatic_project_task_timer/static/description/index.html new file mode 100644 index 000000000..c1336864a --- /dev/null +++ b/automatic_project_task_timer/static/description/index.html @@ -0,0 +1,864 @@ + + + + + + Odoo App 3 Index + + + + + + + + +
+
+
+
+
+ +
+
+
+ Community +
+
+
+
+
+
+

+ Automatic Project Task Timer

+

+ Automatic Running Timer for Project Tasks at the Configured + Stages. +

+
+ +
+
+
+
+
+

+ Key Highlights +

+
+
+
+
+
+ +
+
+

+ Feature Control: +

+

Control the + availability of features from the configuration + settings.

+
+
+
+
+
+
+ +
+
+

+ Timer Activation:

+

Streamline + The timer will be run if it is activated in the + configuration settings.

+
+
+
+
+
+
+ +
+
+

+ Auto-Start Timer:

+

Automatically + starts to count from the beginning whether the + task is moved to In progress stage by changing + the stage by clicking or dragging.

+
+
+
+
+
+
+ +
+
+

+ Time Recording: +

+

Starting time + and ending time will be recorded in the + timesheet. +

+
+
+
+
+
+
+ +
+
+

+ Odoo 17.0 Community : +

+

Available in + Odoo 17.0 + Community.

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

+ Set the User Group for Project as Administrator to see the + Configuration menu. +

+

+ Go to Settings -> Users & Companies -> Users -> Project : + Administrator +

+
+
+
+
+
+
+ +
+
+

+ Configure your custom stage of each project to make the + automatic timer on that particular stage only from the Timer + Configuration menu. +

+

+ Go to Project -> Configuration -> Timer Configuration +

+
+
+
+
+
+
+ +
+
+

+ Timer Configuration +

+

+ Set up your Projects and related Stages. +

+
+
+
+
+
+
+ +
+
+

+ Activate the feature from configuration setting.

+

+ Go to Projects -> Configuration + -> + Settings. + Activate the Task Timer boolean to activate the run timer. +

+
+
+
+
+
+
+ +
+
+

+ Create a new task. +

+

Add a task under the timer configured stage.

+
+
+
+
+
+
+ +
+
+

+ The timer is assigned to zero when a task is in other stage. +

+

+ A real duration field will be seen on the timesheet page. In + the other stages the timer won't be run, and also timesheet not + be recorded. +

+
+
+
+
+
+
+ +
+
+

+ The timer starts to run when a task comes in Configured stage. +

+

+ The timer starts running and timesheet also created with the + starting time. +

+
+
+
+
+
+
+ +
+
+

+ The timer will stop when a task comes to the other stage. +

+

+ The timer stops running when the task moves to any other stage + and the timesheet will update with the ending time also we can + see the time when the timer stops. +

+
+
+
+
+
+
+ +
+
+

+ The timer will also be activated when a task is dragged to the + Configured stage. +

+
+
+
+ +
+ + +
+
+
    +
  • + Real-time tracking starts when the task is in the configured stage. +
  • +
  • + The timer stops and the timesheet is recorded when the task moves to another stage. +
  • +
+
+
+
+
+
+
Version + 17.0.1.0.0|Released on:08th Jan 2024 +
+

+ Initial Commit for Automatic Project Task Timer +

+
+
+
+
+
+
+
+

+ Related Products

+
+
+ +
+
+

+ Our Services

+ +
+
+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Customization

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Support

+
+
+
+
+
+
+ service-icon +
+
+

Hire + Odoo Developer

+
+
+
+
+ +
+
+ service-icon +
+
+

Odoo + Integration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Migration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Consultancy

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Licensing Consultancy

+
+
+
+
+
+
+

+ Our Industries

+
+
+
+
+
+
+ +

Trading

+

Easily procure and sell your products

+
+
+
+
+ +

POS

+

Easy configuration and convivial experience

+
+
+
+
+ +

+ Education

+

A platform for educational management

+
+
+
+
+ +

+ Manufacturing

+

Plan, track and schedule your operations

+
+
+
+
+ +

E-commerce + & Website

+

Mobile friendly, awe-inspiring product pages

+
+
+
+
+ +

Service + Management

+

Keep track of services and invoice

+
+
+
+
+ +

+ Restaurant

+

Run your bar or restaurant methodically

+
+
+
+
+ +

Hotel + Management

+

An all-inclusive hotel management application

+
+
+
+
+
+
+

+ Support

+
+
+
+
+
+
+
+ +
+ Need + Help? +

Got + questions or need help? Get in touch.

+
odoo@cybrosys.com +
+
+
+
+
+
+
+
+ +
+ WhatsApp +

Say hi to + us on WhatsApp!

+
+91 + 99456767686 +
+
+
+
+
+
+
+
+
+ + + + + + + diff --git a/automatic_project_task_timer/static/src/js/form_open.js b/automatic_project_task_timer/static/src/js/form_open.js new file mode 100644 index 000000000..374a2eecc --- /dev/null +++ b/automatic_project_task_timer/static/src/js/form_open.js @@ -0,0 +1,15 @@ +/** @odoo-module **/ +import { patch } from "@web/core/utils/patch"; +import { FormRenderer } from '@web/views/form/form_renderer'; +import { useService } from "@web/core/utils/hooks"; +patch(FormRenderer.prototype, { + // Patched the form render to show the notification for already existing task. + setup(){ + super.setup(); + if(this.props.record.data.is_status_stage) + { + this.notification = useService("notification"); + this.notification.add("Timer will not works properly for already existing task, To make that, Change the stage once again after activating task timer from configuration.", {title: "Warning", type: "danger"}); + } + }, +}); diff --git a/automatic_project_task_timer/static/src/js/task_timer.js b/automatic_project_task_timer/static/src/js/task_timer.js new file mode 100644 index 000000000..25cca0e44 --- /dev/null +++ b/automatic_project_task_timer/static/src/js/task_timer.js @@ -0,0 +1,89 @@ +/** @odoo-module **/ +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"; + +const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl; +// Function for converting the time and return the value in each seconds. +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}`; +} + +export class TaskTimer extends Component { +//Extend component to add TaskTimer + setup() { + this.orm = useService('orm'); + this.state = useState({ + // Duration is expected to be given in minutes + duration:this.props?.value ? 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 () => { + //Check the status while form rendering. + if(this.props.ongoing === undefined && !this.props.record.model.useSampleModel && this.props.record.data.stage_id[0] == this.props.record.data.check_stage) { + const additionalDuration = await this.orm.call('project.task', 'get_working_duration', [this.props.record.resId]); + this.state.duration += additionalDuration; + } + if (this.ongoing) { + this._runTimer(); + } + }); + 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.record.data.duration; + this._runTimer(); + } + else{ + this.state.duration = nextProps.record.data.duration + } + }); + onWillDestroy(() => clearTimeout(this.timer)); + } + //Getting the formatted time duration + get durationFormatted() { + return formatMinutes(this.state.duration); + } + //Function for setting the interval and call in each 1000ms + _runTimer() { + this.timer = setTimeout(() => { + if (this.ongoing) { + this.state.duration += 1 / 60; + this._runTimer(); + } + }, 1000); + } +} + +TaskTimer.template = "TaskTimerTemplate"; +export const taskTimer = { + component: TaskTimer, + supportedTypes : ["float"], +}; +//Adding the widget to the field registry +registry.category("fields").add("task_timer", taskTimer); +registry.category("formatters").add("task_timer", formatMinutes); diff --git a/automatic_project_task_timer/static/src/xml/task_timer_templates.xml b/automatic_project_task_timer/static/src/xml/task_timer_templates.xml new file mode 100644 index 000000000..6a7d39f82 --- /dev/null +++ b/automatic_project_task_timer/static/src/xml/task_timer_templates.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/automatic_project_task_timer/views/project_task_views.xml b/automatic_project_task_timer/views/project_task_views.xml new file mode 100644 index 000000000..b72692d78 --- /dev/null +++ b/automatic_project_task_timer/views/project_task_views.xml @@ -0,0 +1,33 @@ + + + + + project.task.view.form.inherit.automatic.project.task.timer + project.task + + + + + + + + + + + + + + + + diff --git a/automatic_project_task_timer/views/res_config_settings_views.xml b/automatic_project_task_timer/views/res_config_settings_views.xml new file mode 100644 index 000000000..d986f5872 --- /dev/null +++ b/automatic_project_task_timer/views/res_config_settings_views.xml @@ -0,0 +1,21 @@ + + + + + + res.config.settings.view.form.inherit.automatic.project.task.timer + + res.config.settings + + + + + + + + + + diff --git a/automatic_project_task_timer/views/timer_configuration_views.xml b/automatic_project_task_timer/views/timer_configuration_views.xml new file mode 100644 index 000000000..61aceb797 --- /dev/null +++ b/automatic_project_task_timer/views/timer_configuration_views.xml @@ -0,0 +1,26 @@ + + + + + timer.configuration.view.tree + timer.configuration + + + + + + + + + + + Timer Configuration + timer.configuration + tree + + + + +