@ -0,0 +1,48 @@ |
|||
.. 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 |
|||
============= |
|||
* No additional configurations needed |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
License |
|||
------- |
|||
GNU AFFERO GENERAL PUBLIC LICENSE v3.0 (AGPL-3) |
|||
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
|||
|
|||
Credits |
|||
------- |
|||
* Developers: (V17) Ayana KP, |
|||
(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 <https://cybrosys.com/>`__ |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import models |
@ -0,0 +1,51 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
{ |
|||
'name': 'Automatic Project Task Timer', |
|||
'version': '15.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/xml/task_timer_templates.xml', |
|||
]}, |
|||
'images': ['static/description/banner.png'], |
|||
'license': 'AGPL-3', |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': False, |
|||
} |
@ -0,0 +1,5 @@ |
|||
## Module <automatic_project_task_timer> |
|||
#### 21.08.2024 |
|||
#### Version 15.0.1.0.0 |
|||
#### ADD |
|||
- Initial commit for Automatic Project Task Timer |
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import account_analytic_line |
|||
from . import project_task |
|||
from . import res_config_settings |
|||
from . import timer_configuration |
@ -0,0 +1,34 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
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', readonly=1, help='Shows ' |
|||
'the ending time of the timer') |
|||
timer_duration = fields.Float(string='Time Duration(Minutes)', |
|||
help='Shows the real time ') |
@ -0,0 +1,154 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
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: |
|||
start_time = fields.Datetime.from_string( |
|||
time_line.date_start).replace(second=0, |
|||
microsecond=0) |
|||
end_time = fields.Datetime.from_string( |
|||
time_line.date_end).replace(second=0, |
|||
microsecond=0) |
|||
|
|||
diff = end_time - start_time |
|||
|
|||
# Calculate duration in minutes and hours |
|||
minutes_duration = round( |
|||
diff.total_seconds() / 60.0, 2) |
|||
hours_duration = round( |
|||
diff.total_seconds() / (60.0 * 60.0), 2) |
|||
|
|||
# Format durations to two decimal places |
|||
time_line.timer_duration = f"{minutes_duration:05.2f}" |
|||
time_line.unit_amount = f"{hours_duration:05.2f}" |
|||
else: |
|||
time_line.unit_amount = "00.00" |
|||
time_line.timer_duration = "00.00" |
|||
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 |
@ -0,0 +1,33 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
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') |
@ -0,0 +1,73 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Ayana KP(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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
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([]).filtered( |
|||
lambda sol: sol.project_id == projects) |
|||
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 |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 95 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 343 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 9.3 KiB |
@ -0,0 +1,619 @@ |
|||
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;"> |
|||
<!-- TITLE BAR --> |
|||
<div class="d-flex align-items-center justify-content-between" |
|||
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;"> |
|||
<img src="assets/misc/cybrosys-logo.png" width="42" height="42" style="width: 42px; height: 42px;" /> |
|||
<div> |
|||
<div |
|||
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;" |
|||
class="mr-2"> |
|||
<i class="fa fa-check mr-1"></i>Community |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF TITLE BAR --> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<div class="col-sm-12 col-md-12 col-lg-12"> |
|||
<!-- APP HERO --> |
|||
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;"> |
|||
Automatic Project Task Timer |
|||
</h1> |
|||
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">Automatic Running Timer for Project Tasks at the Configured Stages.</p> |
|||
<!-- END OF APP HERO --> |
|||
<img src="assets/screenshots/hero.gif" class="img-responsive" |
|||
style="width: 100%; margin-left: auto; margin-right: auto;" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- NAVIGATION SECTION --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/compass.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Explore This |
|||
Module</h2> |
|||
</div> |
|||
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;"> |
|||
<div class="col-sm-12 col-md-6 my-3"> |
|||
<a href="#overview"> |
|||
<div class="d-flex justify-content-between align-items-center" |
|||
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
|||
<div> |
|||
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span> |
|||
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn |
|||
more about this |
|||
module</span> |
|||
</div> |
|||
<img src="assets/misc/right-arrow.png" width="36" height="36" /> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6 my-3"> |
|||
<a href="#features"> |
|||
<div class="d-flex justify-content-between align-items-center" |
|||
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
|||
<div> |
|||
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span> |
|||
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View |
|||
features of this |
|||
module</span> |
|||
</div> |
|||
<img src="assets/misc/right-arrow.png" width="36" height="36" /> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6 my-3"> |
|||
<a href="#screenshots"> |
|||
<div class="d-flex justify-content-between align-items-center" |
|||
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
|||
<div> |
|||
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span> |
|||
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View |
|||
screenshots for this |
|||
module</span> |
|||
</div> |
|||
<img src="assets/misc/right-arrow.png" width="36" height="36" /> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
<!-- END OF NAVIGATION SECTION --> |
|||
|
|||
<!-- OVERVIEW SECTION --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/pie-chart.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Overview |
|||
</h2> |
|||
</div> |
|||
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;"> |
|||
<div class="col-sm-12 py-4"> |
|||
This module will give the feature of running a timer when a task comes in 'In Progress' stage and stops when it is moved to any other stage |
|||
</div> |
|||
</div> |
|||
<!-- END OF OVERVIEW SECTION --> |
|||
|
|||
<!-- FEATURES SECTION --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/features.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Features |
|||
</h2> |
|||
</div> |
|||
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;"> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2" /> |
|||
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Control the availability of features from the configuration settings.</span> |
|||
</div> |
|||
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2" /> |
|||
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">The timer will be run if it is activated in the configuration settings.</span> |
|||
</div> |
|||
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2" /> |
|||
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Automatically starts to count from the beginning whether the task is moved to In progress stage by changing the stage by clicking or dragging.</span> |
|||
</div> |
|||
|
|||
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2" /> |
|||
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Starting time and ending time will be recorded in the timesheet.</span> |
|||
</div> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2" /> |
|||
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Available in Odoo 15.0 |
|||
Community.</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF FEATURES SECTION --> |
|||
|
|||
<!-- SCREENSHOTS SECTION --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="screenshots"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/pictures.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Screenshots |
|||
</h2> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Set the User Group for Project as Administrator to see the |
|||
Configuration menu. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> |
|||
Go to Settings -> Users & Companies -> Users -> Project : |
|||
Administrator</p> |
|||
<img src="assets/screenshots/1.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Configure your custom stage of each project to make the automatic timer on that particular stage only from the Timer Configuration menu. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> |
|||
Go to Project -> Configuration -> Timer Configuration </p> |
|||
<img src="assets/screenshots/2.png" |
|||
class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Timer Configuration |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> |
|||
Set up your Projects and related Stages.</p> |
|||
<img src="assets/screenshots/3.png" |
|||
class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Activate the feature from configuration setting. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to Projects -> Configuration |
|||
-> |
|||
Settings. |
|||
Activate the Task Timer boolean to activate the run timer.</p> |
|||
<img src="assets/screenshots/4.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Create a new task. |
|||
</h3><p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Add a task under the timer configured stage.</p> |
|||
<img src="assets/screenshots/5.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">The timer is assigned to zero when a task is in other stage. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> 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.</p> |
|||
<img src="assets/screenshots/6.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">The timer starts to run when a task comes in Configured stage. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> The timer starts running and timesheet also created with the starting time.</p> |
|||
<img src="assets/screenshots/7.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">The timer will stop when a task comes to the other stage. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> 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.</p> |
|||
<img src="assets/screenshots/8.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">The timer will also be activated when a task is dragged to the Configured stage.</h3> |
|||
<img src="assets/screenshots/9.png" class="img-thumbnail" style="width:100%;"> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
<!-- END OF SCREENSHOTS SECTION --> |
|||
|
|||
<!-- RELATED PRODUCTS --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/categories.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Related |
|||
Products |
|||
</h2> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<div id="demo1" class="row carousel slide" data-ride="carousel"> |
|||
<!-- The slideshow --> |
|||
<div class="carousel-inner" style="padding: 30px;"> |
|||
<div class="carousel-item" style="min-height: 198.656px;"> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/website_product_attachments/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/1.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/product_visibility_website/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/2.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/website_pdf_preview_snippet/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-https://apps.odoo.com/apps/modules/15.0/wishlist_product_website_backend/responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/3.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
<div class="carousel-item active" |
|||
style="min-height: 198.656px;"> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/wishlist_product_website_backend/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/4.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/website_product_publish/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/5.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
|||
style="float:left"> |
|||
<a href="https://apps.odoo.com/apps/modules/15.0/product_brand_ecommerce/" |
|||
target="_blank"> |
|||
<div style="border-radius:10px"> |
|||
<img class="img img-responsive center-block" |
|||
style="border-radius: 0px;" |
|||
src="assets/modules/6.png"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- Left and right controls --> |
|||
<a class="carousel-control-prev" href="#demo1" data-slide="prev" |
|||
style="width:35px; color:#000"> <span |
|||
class="carousel-control-prev-icon"><i |
|||
class="fa fa-chevron-left" |
|||
style="font-size:24px"></i></span> |
|||
</a> <a class="carousel-control-next" href="#demo1" |
|||
data-slide="next" style="width:35px; color:#000"> |
|||
<span class="carousel-control-next-icon"><i |
|||
class="fa fa-chevron-right" style="font-size:24px"></i></span> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF RELATED PRODUCTS --> |
|||
|
|||
<!-- OUR SERVICES --> |
|||
|
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/star.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our Services |
|||
</h2> |
|||
</div> |
|||
|
|||
<div class="container my-5"> |
|||
<div class="row"> |
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Customization</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Implementation</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Support</h6> |
|||
</div> |
|||
|
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Hire |
|||
Odoo |
|||
Developer</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Integration</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Migration</h6> |
|||
</div> |
|||
|
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Consultancy</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Implementation</h6> |
|||
</div> |
|||
|
|||
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
|||
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
|||
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
|||
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px"> |
|||
</div> |
|||
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
|||
Odoo |
|||
Licensing Consultancy</h6> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- END OF OUR SERVICES --> |
|||
|
|||
<!-- OUR INDUSTRIES --> |
|||
|
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/corporate.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our |
|||
Industries |
|||
</h2> |
|||
</div> |
|||
|
|||
<div class="container my-5"> |
|||
<div class="row"> |
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Trading |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Easily procure |
|||
and |
|||
sell your products</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
POS |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Easy |
|||
configuration |
|||
and convivial experience</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/education-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Education |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
A platform for |
|||
educational management</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Manufacturing |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Plan, track and |
|||
schedule your operations</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
E-commerce & Website |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Mobile |
|||
friendly, |
|||
awe-inspiring product pages</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Service Management |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Keep track of |
|||
services and invoice</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Restaurant |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
Run your bar or |
|||
restaurant methodically</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;"> |
|||
<img src="assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
|||
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
|||
Hotel Management |
|||
</h5> |
|||
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
|||
An |
|||
all-inclusive |
|||
hotel management application</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- END OF OUR INDUSTRIES --> |
|||
|
|||
<!-- SUPPORT --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<div class="d-flex justify-content-center align-items-center mr-2" |
|||
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
|||
<img src="assets/misc/customer-support.png" /> |
|||
</div> |
|||
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Support |
|||
</h2> |
|||
</div> |
|||
<div class="container mt-5"> |
|||
<div class="row"> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;"> |
|||
<div class="mr-4 d-flex justify-content-center align-items-center" |
|||
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;"> |
|||
<img src="assets/misc/support.png" height="48" width="48" style="width: 42px; height: 42px;" /> |
|||
</div> |
|||
<div> |
|||
<h4>Need Help?</h4> |
|||
<p style="line-height: 100%;">Got questions or need help? Get in touch.</p> |
|||
<a href="mailto:odoo@cybrosys.com"> |
|||
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;"> |
|||
odoo@cybrosys.com</p> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;"> |
|||
<div class="mr-4 d-flex justify-content-center align-items-center" |
|||
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;"> |
|||
<img src="assets/misc/whatsapp.png" height="52" width="52" style="width: 52px; height: 52px;" /> |
|||
</div> |
|||
<div> |
|||
<h4>WhatsApp</h4> |
|||
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p> |
|||
<a href="https://api.whatsapp.com/send?phone=918606827707"> |
|||
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">+91 86068 |
|||
27707</p> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center"> |
|||
<img src="assets/misc/logo.png" width="144" height="31" style="width:144px; height: 31px; margin-top: 40px;" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF SUPPORT --> |
@ -0,0 +1,63 @@ |
|||
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'); |
|||
const { useState } = owl.hooks; |
|||
|
|||
var _t = core._t; |
|||
|
|||
var TimeCounter = AbstractField.extend({ |
|||
|
|||
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) { |
|||
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); |
|||
}); |
|||
}); |
|||
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)); |
|||
}, |
|||
|
|||
_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($('<span>' + moment.utc(this.duration).format("HH:mm:ss") + '</span>')); |
|||
}, |
|||
}); |
|||
TimeCounter.template = "TaskTimerTemplate"; |
|||
field_registry.add('task_timer', TimeCounter); |
|||
}); |
|||
|
|||
|
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!--Template for getting the timer widget.--> |
|||
<templates id="template" xml:space="preserve"> |
|||
<t t-name="TaskTimerTemplate" owl="1"> |
|||
<span t-if="props.readonly" t-esc="durationFormatted"/> |
|||
<input t-else="" t-att-id="props.id" t-ref="numpadDecimal" t-att-placeholder="props.placeholder" inputmode="numeric" class="o_input" /> |
|||
</t> |
|||
</templates> |
@ -0,0 +1,45 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<!-- Adding the relative fields in 'project.task' module--> |
|||
<record id="view_task_form2" model="ir.ui.view"> |
|||
<field name="name">project.task.view.form.inherit.automatic.project.task.timer</field> |
|||
<field name="model">project.task</field> |
|||
<field name="inherit_id" ref="project.view_task_form2"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='tag_ids']" position="after"> |
|||
<label for="task_timer"/> |
|||
<div class="o_row" style="display: inline-block;"> |
|||
<field name="task_timer" widget="boolean_toggle" |
|||
invisible="True"/> |
|||
</div> |
|||
<field name="is_status_stage" invisible="True"/> |
|||
<field name="check_stage" invisible="True"/> |
|||
</xpath> |
|||
<xpath expr="//div[@name='button_box']" position="inside"> |
|||
<div style="margin-top:10px;"> |
|||
<widget name="web_ribbon" text="In Progress" |
|||
attrs="{'invisible': [('task_timer', '=', False)]}"/> |
|||
</div> |
|||
</xpath> |
|||
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='unit_amount']" |
|||
position="before"> |
|||
<field name="date_start" required="1"/> |
|||
<field name="date_end"/> |
|||
<field name="timer_duration" invisible="1"/> |
|||
</xpath> |
|||
<xpath expr="//field[@name='progress']" position="after"> |
|||
<field name="is_user_working" invisible="1"/> |
|||
<label for="duration"/> |
|||
<div> |
|||
<button style="pointer-events: none;" |
|||
class="oe_inline label label-default"> |
|||
<field name="duration" id="duration" widget="task_timer" |
|||
style="color: red;" |
|||
attrs="{'readonly': [('is_user_working', '=', True)]}" |
|||
sum="real duration"/> |
|||
</button> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,28 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Adding task timer in configuration--> |
|||
<record id="res_config_settings_view_form" model="ir.ui.view"> |
|||
<field name="name">res.config.settings.view.form.inherit.automatic.project.task.timer</field> |
|||
<field name="model">res.config.settings</field> |
|||
<field name="inherit_id" |
|||
ref="project.res_config_settings_view_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[@id='tasks_management']" |
|||
position="after"> |
|||
<div class="row mt16 o_settings_container"> |
|||
<div class="col-12 col-lg-6 o_setting_box"> |
|||
<div class="o_setting_left_pane"> |
|||
<field name="timer_setting"/> |
|||
</div> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="timer_setting" string="Task Timer"/> |
|||
<div class="text-muted"> |
|||
Timer will automatically activate for tasks in progress stage |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,26 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Tree view record of the timer configuration model--> |
|||
<record id="timer_configuration_view_tree" model="ir.ui.view"> |
|||
<field name="name">timer.configuration.view.tree</field> |
|||
<field name="model">timer.configuration</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Configuration" editable="bottom"> |
|||
<field name="project_id"/> |
|||
<field name="stage_id"/> |
|||
<field name="stage_ids" invisible="1"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- Record action for timer configuration model--> |
|||
<record id="timer_configuration_action" model="ir.actions.act_window"> |
|||
<field name="name">Timer Configuration</field> |
|||
<field name="res_model">timer.configuration</field> |
|||
<field name="view_mode">tree</field> |
|||
</record> |
|||
<!-- Menu action for timer configuration model--> |
|||
<menuitem id="timer_configuration_menu_root" name="Timer Configuration" |
|||
action="timer_configuration_action" |
|||
parent="project.menu_project_config"> |
|||
</menuitem> |
|||
</odoo> |