diff --git a/pos_timesheet/README.rst b/pos_timesheet/README.rst new file mode 100644 index 000000000..bb9e367ff --- /dev/null +++ b/pos_timesheet/README.rst @@ -0,0 +1,46 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg + :target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +POS Timesheet +============= +Efficiently track employees' work hours in POS. + +Configuration +============= +No configuration + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +General Public License, Version 3 (LGPL v3). +(http://www.gnu.org/licenses/lgpl-3.0-standalone.html) + +Credits +------- +Developer: (V17) Mohammed Hisam , 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/pos_timesheet/__init__.py b/pos_timesheet/__init__.py new file mode 100644 index 000000000..fa220822b --- /dev/null +++ b/pos_timesheet/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models diff --git a/pos_timesheet/__manifest__.py b/pos_timesheet/__manifest__.py new file mode 100644 index 000000000..665908d03 --- /dev/null +++ b/pos_timesheet/__manifest__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +{ + 'name': 'POS Timesheet', + 'version': '17.0.1.0.0', + 'category': 'Point of Sale', + 'summary': """Efficiently track employees' work hours in POS.""", + 'description':"""This module enhances the Point of Sale (POS) + functionality by automatically calculating timesheets for employees based + on their activities in the POS.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['point_of_sale', 'pos_hr', 'hr_timesheet', 'project'], + 'data': [ + 'views/res_config_settings_views.xml', + 'views/pos_session_views.xml', + ], + 'assets': { + 'point_of_sale._assets_pos': [ + 'pos_timesheet/static/src/models/pos_store.js', + 'pos_timesheet/static/src/navbar/navbar.js', + 'pos_timesheet/static/src/navbar/navbar.xml', + ], + }, + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/pos_timesheet/doc/RELEASE_NOTES.md b/pos_timesheet/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..3fd6cb905 --- /dev/null +++ b/pos_timesheet/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 28.02.2024 +#### Version 17.0.1.0.0 +#### ADD +- Initial commit for POS Timesheet diff --git a/pos_timesheet/models/__init__.py b/pos_timesheet/models/__init__.py new file mode 100644 index 000000000..446cb0f25 --- /dev/null +++ b/pos_timesheet/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import res_config_settings +from . import pos_config +from . import pos_session diff --git a/pos_timesheet/models/pos_config.py b/pos_timesheet/models/pos_config.py new file mode 100644 index 000000000..6bcc25a5b --- /dev/null +++ b/pos_timesheet/models/pos_config.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models + + +class PosConfig(models.Model): + """Inherits the PosConfig class for adding fields""" + _inherit = 'pos.config' + + time_log = fields.Boolean(string="Time Log", default=False, + help="Track employees timesheet in pos") + project_id = fields.Many2one( + 'project.project', + string="Project", + help="Project for the timesheet") diff --git a/pos_timesheet/models/pos_session.py b/pos_timesheet/models/pos_session.py new file mode 100644 index 000000000..ca98acfc6 --- /dev/null +++ b/pos_timesheet/models/pos_session.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import api, fields, models, _ + + +class PosSession(models.Model): + """Inherits the PosSession class for adding fields and functions""" + _inherit = 'pos.session' + + task_id = fields.Many2one("project.task", string="Task", + help="Session Timesheet Task", + required=True, ondelete='cascade', default=False) + + @api.model_create_multi + def create(self, vals_list): + """Create Task for add timesheet""" + result = super().create(vals_list) + + if result.config_id.module_pos_hr and result.config_id.time_log: + result.task_id = self.env['project.task'].create({ + 'name': result.name, + 'project_id': result.config_id.project_id.id, + 'company_id': result.config_id.company_id.id + }) + return result + + def _pos_ui_models_to_load(self): + """loads models to the UI""" + result = super()._pos_ui_models_to_load() + result.append('account.analytic.line') + return result + + def _loader_params_account_analytic_line(self): + """Returns loader params for account""" + return { + 'search_params': { + 'domain': [('task_id', '=', self.task_id.id), + ('date', '=', fields.Date.context_today(self))], + 'fields': ['employee_id', 'unit_amount'], + }, + } + + def _get_pos_ui_account_analytic_line(self, params): + """Returns the account analytics line for the pos""" + return self.env['account.analytic.line'].search_read(**params['search_params']) + + + def _loader_params_pos_session(self): + """Loading parameters to the session""" + result = super()._loader_params_pos_session() + result['search_params']['fields'].append('task_id') + return result + + def set_timesheet(self, data): + """Update Timesheet of the employee""" + for timesheet in data: + if timesheet['workMinutes'] > 0: + hours = timesheet['workMinutes'] / 60 + session_id = self.browse(timesheet['sessionId']) + timestamp_seconds = timesheet['checkInTime'] / 1000 + date_time = fields.datetime.fromtimestamp(timestamp_seconds) + date_only = date_time.date() + employee_timesheet = self.env['account.analytic.line'].search( + [('task_id', '=', session_id.task_id.id), + ('date', '=', date_only), + ('employee_id', '=', timesheet['cashierId'])], limit=1) + if employee_timesheet: + employee_timesheet.unit_amount += hours + else: + self.env['account.analytic.line'].create({ + 'task_id': session_id.task_id.id, + 'employee_id': timesheet['cashierId'], + 'name': session_id.name, + 'date': date_only, + 'unit_amount': hours + }) + return True + + def show_time_log(self): + """Show the task its contained timesheet for the session""" + return { + 'name': _('Time Log'), + 'type': 'ir.actions.act_window', + 'res_model': 'project.task', + 'view_mode': 'form', + 'res_id': self.task_id.id, + } diff --git a/pos_timesheet/models/res_config_settings.py b/pos_timesheet/models/res_config_settings.py new file mode 100644 index 000000000..7e7825b74 --- /dev/null +++ b/pos_timesheet/models/res_config_settings.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Mohammed Hisam (odoo@cybrosysy.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + """Inherits the default settings for the ResConfig model""" + _inherit = 'res.config.settings' + + pos_time_log = fields.Boolean( + related="pos_config_id.time_log", + string="Time Log", + help="Track employees timesheet in pos", + readonly=False) + pos_project_id = fields.Many2one( + related='pos_config_id.project_id', + string="Project", + help="Project for the timesheet", + required=True, + readonly=False) diff --git a/pos_timesheet/static/description/assets/icons/capture (1).png b/pos_timesheet/static/description/assets/icons/capture (1).png new file mode 100644 index 000000000..8824deafc Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/capture (1).png differ diff --git a/pos_timesheet/static/description/assets/icons/check.png b/pos_timesheet/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/check.png differ diff --git a/pos_timesheet/static/description/assets/icons/chevron.png b/pos_timesheet/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/chevron.png differ diff --git a/pos_timesheet/static/description/assets/icons/cogs.png b/pos_timesheet/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/cogs.png differ diff --git a/pos_timesheet/static/description/assets/icons/consultation.png b/pos_timesheet/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/consultation.png differ diff --git a/pos_timesheet/static/description/assets/icons/ecom-black.png b/pos_timesheet/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/ecom-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/education-black.png b/pos_timesheet/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/education-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/hotel-black.png b/pos_timesheet/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/hotel-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/img.png b/pos_timesheet/static/description/assets/icons/img.png new file mode 100644 index 000000000..70197f477 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/img.png differ diff --git a/pos_timesheet/static/description/assets/icons/license.png b/pos_timesheet/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/license.png differ diff --git a/pos_timesheet/static/description/assets/icons/lifebuoy.png b/pos_timesheet/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/lifebuoy.png differ diff --git a/pos_timesheet/static/description/assets/icons/manufacturing-black.png b/pos_timesheet/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/manufacturing-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/photo-capture.png b/pos_timesheet/static/description/assets/icons/photo-capture.png new file mode 100644 index 000000000..06c111758 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/photo-capture.png differ diff --git a/pos_timesheet/static/description/assets/icons/pos-black.png b/pos_timesheet/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/pos-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/puzzle.png b/pos_timesheet/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/puzzle.png differ diff --git a/pos_timesheet/static/description/assets/icons/restaurant-black.png b/pos_timesheet/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/restaurant-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/service-black.png b/pos_timesheet/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/service-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/trading-black.png b/pos_timesheet/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/trading-black.png differ diff --git a/pos_timesheet/static/description/assets/icons/training.png b/pos_timesheet/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/training.png differ diff --git a/pos_timesheet/static/description/assets/icons/update.png b/pos_timesheet/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/update.png differ diff --git a/pos_timesheet/static/description/assets/icons/user.png b/pos_timesheet/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/user.png differ diff --git a/pos_timesheet/static/description/assets/icons/wrench.png b/pos_timesheet/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/pos_timesheet/static/description/assets/icons/wrench.png differ diff --git a/pos_timesheet/static/description/assets/misc/Cybrosys R.png b/pos_timesheet/static/description/assets/misc/Cybrosys R.png new file mode 100644 index 000000000..da4058087 Binary files /dev/null and b/pos_timesheet/static/description/assets/misc/Cybrosys R.png differ diff --git a/pos_timesheet/static/description/assets/misc/email.svg b/pos_timesheet/static/description/assets/misc/email.svg new file mode 100644 index 000000000..15291cdc3 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/email.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/phone.svg b/pos_timesheet/static/description/assets/misc/phone.svg new file mode 100644 index 000000000..b7bd7f251 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/pos_timesheet/static/description/assets/misc/star (1) 2.svg b/pos_timesheet/static/description/assets/misc/star (1) 2.svg new file mode 100644 index 000000000..5ae9f507a --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/star (1) 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/support (1) 1.svg b/pos_timesheet/static/description/assets/misc/support (1) 1.svg new file mode 100644 index 000000000..7d37a8f30 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/support-email.svg b/pos_timesheet/static/description/assets/misc/support-email.svg new file mode 100644 index 000000000..eb70370d6 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/tick-mark.svg b/pos_timesheet/static/description/assets/misc/tick-mark.svg new file mode 100644 index 000000000..2dbb40187 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/tick-mark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/whatsapp 1.svg b/pos_timesheet/static/description/assets/misc/whatsapp 1.svg new file mode 100644 index 000000000..0bfaf8fc6 --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/misc/whatsapp.svg b/pos_timesheet/static/description/assets/misc/whatsapp.svg new file mode 100644 index 000000000..b618aea1d --- /dev/null +++ b/pos_timesheet/static/description/assets/misc/whatsapp.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pos_timesheet/static/description/assets/modules/1.png b/pos_timesheet/static/description/assets/modules/1.png new file mode 100644 index 000000000..3a5c1ae0f Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/1.png differ diff --git a/pos_timesheet/static/description/assets/modules/2.png b/pos_timesheet/static/description/assets/modules/2.png new file mode 100644 index 000000000..78b1287e4 Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/2.png differ diff --git a/pos_timesheet/static/description/assets/modules/3.png b/pos_timesheet/static/description/assets/modules/3.png new file mode 100644 index 000000000..0bcbed5d0 Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/3.png differ diff --git a/pos_timesheet/static/description/assets/modules/4.png b/pos_timesheet/static/description/assets/modules/4.png new file mode 100644 index 000000000..961ecb1e1 Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/4.png differ diff --git a/pos_timesheet/static/description/assets/modules/5.png b/pos_timesheet/static/description/assets/modules/5.png new file mode 100644 index 000000000..910b3436d Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/5.png differ diff --git a/pos_timesheet/static/description/assets/modules/6.png b/pos_timesheet/static/description/assets/modules/6.png new file mode 100644 index 000000000..630edfde2 Binary files /dev/null and b/pos_timesheet/static/description/assets/modules/6.png differ diff --git a/pos_timesheet/static/description/assets/screenshots/1.png b/pos_timesheet/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..f8351335e Binary files /dev/null and b/pos_timesheet/static/description/assets/screenshots/1.png differ diff --git a/pos_timesheet/static/description/assets/screenshots/2.png b/pos_timesheet/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..fa734cdb0 Binary files /dev/null and b/pos_timesheet/static/description/assets/screenshots/2.png differ diff --git a/pos_timesheet/static/description/assets/screenshots/3.png b/pos_timesheet/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..4903e3b14 Binary files /dev/null and b/pos_timesheet/static/description/assets/screenshots/3.png differ diff --git a/pos_timesheet/static/description/assets/screenshots/4.png b/pos_timesheet/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..1669bf9d7 Binary files /dev/null and b/pos_timesheet/static/description/assets/screenshots/4.png differ diff --git a/pos_timesheet/static/description/assets/screenshots/hero.gif b/pos_timesheet/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..77975e2c8 Binary files /dev/null and b/pos_timesheet/static/description/assets/screenshots/hero.gif differ diff --git a/pos_timesheet/static/description/banner.jpg b/pos_timesheet/static/description/banner.jpg new file mode 100644 index 000000000..424868638 Binary files /dev/null and b/pos_timesheet/static/description/banner.jpg differ diff --git a/pos_timesheet/static/description/icon.png b/pos_timesheet/static/description/icon.png new file mode 100644 index 000000000..b2f9109a7 Binary files /dev/null and b/pos_timesheet/static/description/icon.png differ diff --git a/pos_timesheet/static/description/index.html b/pos_timesheet/static/description/index.html new file mode 100644 index 000000000..a4ea7d803 --- /dev/null +++ b/pos_timesheet/static/description/index.html @@ -0,0 +1,751 @@ + + + + + + + Odoo App 3 Index + + + + + + + + +
+
+
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+
+
+
+

+ POS Timesheet

+

+ Add Timesheet For POS. +

+
+ +
+
+
+
+
+

+ Key Highlights +

+
+
+
+
+
+ +
+
+

+ Timesheet for POS.

+

Add Timesheet + for employees based on their activities in + the POS. +

+
+
+
+
+
+
+ +
+
+

+ Works in POS offline mode.

+

Track Employee + activity in POS offline mode. +

+
+
+
+
+
+
+ +
+
+

+ Using Project and Tasks.

+

A task will be + created in the name of the session in the + project selected in the POS configuration + settings. +

+
+
+
+
+
+
+ +
+
+

+ View worked hours in the POS menu.

+

View the + employees' worked hours in real-time in the POS + menu. +

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

+ Enable Multi Employee per Session, then the + Time Log option will be visible in the + Configuration + Settings of POS and you can also set a + project for the timesheet.

+
+
+
+
+
+
+ +
+
+

+ The employee can see the total work hours, + last check-in time, and time worked since + the last check-in time on the menu.

+
+
+
+
+
+
+ +
+
+

+ You can easily navigate to the task + associated with the session by clicking + timelog smart tab.

+
+
+
+
+
+
+ +
+
+

+ You can see all the employees timesheet in + the task timesheet tab.

+
+
+
+
+
+
+
    +
  • + Track Employee + activity in POS online/offline mode. +
  • +
  • + Using Project + and Tasks makes it easier. +
  • +
  • + View the + employees' worked hours in real-time in the POS + menu. +
  • + +
+
+
+
+
+
+
Version + 17.0.1.0.0|Released on:28th February 2024 +
+

+ Initial Commit for POS Timesheet.

+
+
+
+
+
+
+
+

+ 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/pos_timesheet/static/src/models/pos_store.js b/pos_timesheet/static/src/models/pos_store.js new file mode 100644 index 000000000..9cd9c69ab --- /dev/null +++ b/pos_timesheet/static/src/models/pos_store.js @@ -0,0 +1,148 @@ +/** @odoo-module */ +import { patch } from "@web/core/utils/patch"; +import { PosStore } from "@point_of_sale/app/store/pos_store"; + +patch(PosStore.prototype, { + /** + * @override + */ + async _processData(loadedData) { + await super._processData(...arguments); + if (this.config.module_pos_hr && this.config.time_log) { + this.timesheet = loadedData['account.analytic.line']; + this.workedTime = []; + } + }, + + /** + * @override + * Add timesheet in to server when go to backend + */ + async closePos() { + if (this.config.module_pos_hr && this.config.time_log) { + return this._handleTimesheet(() => super.closePos(...arguments)); + } else { + return super.closePos(...arguments); + } + }, + + /** + * @override + * If the 'Multi Employee persession' and 'Time Log' enabled in POS configuration, + * handles timesheet processing before resetting the cashier. + */ + + reset_cashier() { + if (this.config.module_pos_hr && this.config.time_log) { + return this._handleTimesheet(() => super.reset_cashier(...arguments)); + } else { + return super.reset_cashier(...arguments); + } + }, + + /** + * @override + * If the 'Multi Employee persession' and 'Time Log' enabled in POS configuration, + * handles timesheet processing before setting the cashier. + * @param {Object} employee - Employee object representing the cashier. + */ + set_cashier(employee) { + if (this.config.module_pos_hr && this.config.time_log) { + return this._handleTimesheet(() => super.set_cashier(...arguments), employee); + } else { + return super.set_cashier(...arguments); + } + }, + + /** + * Handles timesheet processing asynchronously. + * Executes a callback function and handles timesheet operations based on the POS configuration. + * @param {Function} callback - Callback function to execute. + * @param {Object} employee - Employee object representing the cashier or null. + */ + + _handleTimesheet(callback, employee = null) { + const data = this.prepareTimesheet(); + return this.sendTimesheet(data) + .then(response => { + this.setTimesheet(response, employee); + }) + .catch(errData => { + this.setTimesheet(errData, employee); + }) + .finally(() => { + callback(); + }); + }, + + /** + * Sets the timesheet data to localStorage. + * @param {Array} timesheetData - Timesheet data to set. + * @param {Object} employee - Employee object representing the cashier. + */ + setTimesheet(timesheetData, employee = null) { + if (employee) { + const cashierData = { + cashierId: employee.id, + checkInTime: Date.now(), + sessionId: this.pos_session.id + }; + if (timesheetData) { + timesheetData.push(cashierData); + } else { + timesheetData = [cashierData]; + } + } + localStorage.setItem('timesheetData', JSON.stringify(timesheetData)); + }, + + /** + * Sends timesheet data to the server. + * @param {Array} timesheetData - Timesheet data to send. + * @return {null} success or no timesheetData, if error {Object} timesheetData + */ + sendTimesheet(timesheetData) { + return new Promise((resolve, reject) => { + if (timesheetData) { + this.orm.call('pos.session', 'set_timesheet', ['', timesheetData]) + .then(res => { + timesheetData.forEach(data => { + let index = this.workedTime.findIndex(item => item.cashierId === data.cashierId); + if (index !== -1) { + this.workedTime[index].minutes += data.workMinutes; + } else { + this.workedTime.push({ cashierId: data.cashierId, minutes: data.workMinutes }); + } + }); + resolve(null); + }) + .catch(err => { + reject(timesheetData); + }); + } else { + resolve(null); + } + }); + }, + + /** + * Prepares timesheet data for sending to the server. + * Checks for existing timesheet data in localStorage and adjusts work minutes. + * @returns {Array|null} Prepared timesheet data. + */ + prepareTimesheet() { + const timesheetData = JSON.parse(localStorage.getItem('timesheetData')); + if (timesheetData && timesheetData.length != 0){ + if (!timesheetData.at(-1).hasOwnProperty('checkOutTime')) { + timesheetData.at(-1)['checkOutTime'] = Date.now(); + const timeDiff = timesheetData.at(-1)['checkOutTime'] - timesheetData.at(-1)['checkInTime']; + timesheetData.at(-1)['workMinutes'] = Math.floor(timeDiff / (1000 * 60)); + if (timesheetData.at(-1)['workMinutes'] <= 0) { + timesheetData.pop(); + } + } + return timesheetData; + } + return null; + } +}); diff --git a/pos_timesheet/static/src/navbar/navbar.js b/pos_timesheet/static/src/navbar/navbar.js new file mode 100644 index 000000000..f9a0c3cc4 --- /dev/null +++ b/pos_timesheet/static/src/navbar/navbar.js @@ -0,0 +1,119 @@ +/** @odoo-module */ + +import { Navbar } from "@point_of_sale/app/navbar/navbar"; +import { useState, onWillStart, useExternalListener } from "@odoo/owl"; +import { patch } from "@web/core/utils/patch"; + +patch(Navbar.prototype, { + /** + * @override + * Sets up event listeners. + */ + setup() { + super.setup(...arguments); + onWillStart(this.getWorkedTime); + useExternalListener(window, 'beforeunload', this.beforeUnload.bind(this)); + }, + + /** + * @override + * Add timesheet in to server when Close Session. + */ + async closeSession() { + if (this.pos.config.module_pos_hr && this.pos.config.time_log) { + return this.pos._handleTimesheet(() => super.closeSession(...arguments)); + } else { + return super.closeSession(...arguments); + } + }, + + /** + * Event handler triggered before the window unloads. + * eg:- leave the pos by changing the url or closing website etc.. + * set CheckoutTime and WorkedMinutes save in to session. + */ + beforeUnload() { + const timesheetData = this.pos.prepareTimesheet(); + localStorage.setItem('timesheetData', JSON.stringify(timesheetData)); + }, + + /** + * Retrieves worked time data and sets it to the POS instance. + */ + getWorkedTime() { + const datas = this.pos.timesheet; + const workedTime = datas.map(data => ({ + 'cashierId': data['employee_id'][0], + 'minutes': Math.floor(data['unit_amount'] * 60) + })); + this.pos.workedTime = workedTime; + }, + + /** + * Getter for the check-in time. + * @returns {string} Formatted check-in time. + */ + get checkInTime() { + const timesheetData = JSON.parse(localStorage.getItem('timesheetData')); + const checkInTime = timesheetData ? timesheetData.at(-1)['checkInTime'] : Date.now(); + const formattedDate = new Intl.DateTimeFormat('en-US', { + hour: '2-digit', + minute: '2-digit', + hour12: true + }).format(checkInTime); + return formattedDate; + }, + + /** + * Getter for the current worked time. + * @returns {string} Formatted current worked time. + */ + get workedTime() { + const [hours, minutes] = this.currentWorkedTime(); + return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`; + }, + + /** + * Getter for the total today's worked time. + * @returns {string} Formatted total worked time. + */ + get totalWorkedTime() { + let minutes = 0; + const workerData = this.pos.workedTime; + const timesheetData = JSON.parse(localStorage.getItem('timesheetData')); + const cashierId = this.pos.cashier.id; + + if (timesheetData) { + const cashierLocalTimesheet = timesheetData.filter(data => data.cashierId === cashierId && data?.workMinutes); + minutes += cashierLocalTimesheet.reduce((sum, data) => sum + data.workMinutes, 0); + } + + const cashierData = workerData.find(data => data['cashierId'] === cashierId); + minutes += cashierData ? parseInt(cashierData['minutes']) : 0; + + const [currentHours, currentMinutes] = this.currentWorkedTime(); + let hours = currentHours; + minutes += currentMinutes; + + const extraHour = Math.floor(minutes / 60); + minutes %= 60; + hours += extraHour; + + return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`; + }, + + /** + * Retrieves the current worked time. + * @returns {Array} Array containing hours and minutes of current worked time. + */ + currentWorkedTime() { + const timesheetData = JSON.parse(localStorage.getItem('timesheetData')); + const checkInTime = timesheetData ? timesheetData.at(-1)['checkInTime'] : Date.now(); + const currentTime = Date.now(); + const differenceMs = Math.abs(currentTime - checkInTime); + const hours = Math.floor(differenceMs / (1000 * 60 * 60)); + const minutes = Math.floor((differenceMs % (1000 * 60 * 60)) / (1000 * 60)); + return [hours, minutes]; + } + +}); diff --git a/pos_timesheet/static/src/navbar/navbar.xml b/pos_timesheet/static/src/navbar/navbar.xml new file mode 100644 index 000000000..6c64bcafa --- /dev/null +++ b/pos_timesheet/static/src/navbar/navbar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/pos_timesheet/views/pos_session_views.xml b/pos_timesheet/views/pos_session_views.xml new file mode 100644 index 000000000..d1dcdf6e7 --- /dev/null +++ b/pos_timesheet/views/pos_session_views.xml @@ -0,0 +1,19 @@ + + + + pos.session.view.form.inherit.pos.timesheet + pos.session + + + + + + + + + + diff --git a/pos_timesheet/views/res_config_settings_views.xml b/pos_timesheet/views/res_config_settings_views.xml new file mode 100644 index 000000000..153cf1665 --- /dev/null +++ b/pos_timesheet/views/res_config_settings_views.xml @@ -0,0 +1,38 @@ + + + + + res.config.settings.view.form.inherit.pos.timesheet + res.config.settings + + + + + +
+
+
+
+
+
+
+
+
\ No newline at end of file