diff --git a/sale_timesheet_manager/__init__.py b/sale_timesheet_manager/__init__.py
new file mode 100644
index 00000000..91c5580f
--- /dev/null
+++ b/sale_timesheet_manager/__init__.py
@@ -0,0 +1,2 @@
+from . import controllers
+from . import models
diff --git a/sale_timesheet_manager/__manifest__.py b/sale_timesheet_manager/__manifest__.py
new file mode 100644
index 00000000..0343b5c2
--- /dev/null
+++ b/sale_timesheet_manager/__manifest__.py
@@ -0,0 +1,23 @@
+# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
+
+{
+ 'name': 'Hibou Project Time Manager',
+ 'version': '13.0.1.3.0',
+ 'category': 'Warehouse',
+ 'author': 'Hibou Corp.',
+ 'license': 'OPL-1',
+ 'website': 'https://hibou.io/',
+ 'depends': [
+ 'sale_timesheet',
+ 'website',
+ ],
+ 'data': [
+ 'security/ir.model.access.csv',
+ # 'views/project_views.xml',
+ 'views/time_manager_templates.xml',
+ 'views/web_assets.xml',
+ ],
+ 'installable': True,
+ 'application': False,
+ 'auto_install': False,
+ }
diff --git a/sale_timesheet_manager/controllers/__init__.py b/sale_timesheet_manager/controllers/__init__.py
new file mode 100644
index 00000000..8c3feb6f
--- /dev/null
+++ b/sale_timesheet_manager/controllers/__init__.py
@@ -0,0 +1 @@
+from . import portal
diff --git a/sale_timesheet_manager/controllers/portal.py b/sale_timesheet_manager/controllers/portal.py
new file mode 100644
index 00000000..4c926b79
--- /dev/null
+++ b/sale_timesheet_manager/controllers/portal.py
@@ -0,0 +1,20 @@
+from odoo import _
+from odoo.http import Controller, request, route
+from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
+from odoo.exceptions import AccessError, MissingError
+from odoo.http import request
+
+from logging import getLogger as Logs
+_logger = Logs(__name__)
+
+
+class SaleTimesheetManager(Controller):
+ @route('/my/task/time/manager', type='http', auth='public', website=True)
+ def portal_my_timesheet_manager(self, **kwargs):
+ user = request.env.user
+ vals = {
+ 'user': user,
+ 'projects': user._get_tasks_grouped_by_project(),
+ }
+
+ return request.render('sale_timesheet_manager.dashboard', vals)
diff --git a/sale_timesheet_manager/data/ir_cron.xml b/sale_timesheet_manager/data/ir_cron.xml
new file mode 100644
index 00000000..e959998b
--- /dev/null
+++ b/sale_timesheet_manager/data/ir_cron.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/sale_timesheet_manager/models/__init__.py b/sale_timesheet_manager/models/__init__.py
new file mode 100644
index 00000000..35fe6dbb
--- /dev/null
+++ b/sale_timesheet_manager/models/__init__.py
@@ -0,0 +1,2 @@
+from . import project
+from . import users
diff --git a/sale_timesheet_manager/models/project.py b/sale_timesheet_manager/models/project.py
new file mode 100644
index 00000000..0dbc8970
--- /dev/null
+++ b/sale_timesheet_manager/models/project.py
@@ -0,0 +1,45 @@
+from odoo import api, fields, models
+
+from logging import getLogger as Logs
+_logger = Logs(__name__)
+
+
+class ProjectTask(models.Model):
+ _inherit = 'project.task'
+
+ time_manager_ids = fields.One2many('project.task.time.manager', 'task_id', string='Uncommitted time entries.')
+
+
+class ProjectTaskTimeManager(models.Model):
+ _name = 'project.task.time.manager'
+ _description = 'Used to hold arbitrary data as o2m lines until it is committed via user or server action at EOD'
+
+ # Relational Fields
+ task_id = fields.Many2one('project.task', string='Parent Task')
+ time_line_ids = fields.One2many('project.task.time.manager.line', 'time_manager_id')
+ user_id = fields.Many2one('res.user', string='')
+
+
+class ProjectTaskTimeManagerLine(models.Model):
+ _name = 'project.task.time.manager.line'
+ _description = 'Informational time lines that hold data until committed'
+
+ # Relational Fields
+ time_manager_id = fields.Many2one('project.task.time.manager')
+ user_id = fields.Many2one('res.user', string='Timesheet User')
+
+ # Informational Fields
+ user_confirmed = fields.Boolean('User Confirmed Time')
+ cron_confirmed = fields.Boolean('Cron Confirmed Time')
+
+ date_start = fields.Date('Time Started')
+ date_end = fields.Date('Time Finished')
+ duration = fields.Float('Time Duration', compute='_compute_time_line_duration')
+
+ def _compute_time_line_duration(self):
+ for line in self:
+ if line.date_start and line.date_end:
+ time = line.date_start + line.date_end
+ line.duration = float(time.hours)
+ else:
+ line.duration = 0
diff --git a/sale_timesheet_manager/models/users.py b/sale_timesheet_manager/models/users.py
new file mode 100644
index 00000000..7348392e
--- /dev/null
+++ b/sale_timesheet_manager/models/users.py
@@ -0,0 +1,17 @@
+from odoo import api, fields, models
+
+from logging import getLogger as Logs
+_logger = Logs(__name__)
+
+class ResUsers(models.Model):
+ _inherit = 'res.users'
+
+ @api.model
+ def _get_tasks_grouped_by_project(self):
+ self.ensure_one()
+ res = {}
+ for task in self.env['project.task'].search([('user_id', '=', self.id)]):
+ res.setdefault(task.project_id, []).append(task)
+ _logger.warn('-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-')
+ _logger.warn(res)
+ return res
diff --git a/sale_timesheet_manager/security/ir.model.access.csv b/sale_timesheet_manager/security/ir.model.access.csv
new file mode 100644
index 00000000..f6018a41
--- /dev/null
+++ b/sale_timesheet_manager/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"manage_project_task_time_manager","manage project time manager","model_project_task_time_manager","base.group_user",1,1,1,1
+"manage_project_task_time_manager_line","manage project time manager line","model_project_task_time_manager_line","base.group_user",1,1,1,1
\ No newline at end of file
diff --git a/sale_timesheet_manager/src/js/sale_time_manager.js b/sale_timesheet_manager/src/js/sale_time_manager.js
new file mode 100644
index 00000000..6569e7f9
--- /dev/null
+++ b/sale_timesheet_manager/src/js/sale_time_manager.js
@@ -0,0 +1,11 @@
+odoo.define('sale_timesheet_manager.main', function (require) {
+ "use strict";
+
+ $(document).ready(function () {
+
+ console.log('Sale Time Manager Loaded');
+
+ });
+
+
+});
\ No newline at end of file
diff --git a/sale_timesheet_manager/views/project_views.xml b/sale_timesheet_manager/views/project_views.xml
new file mode 100644
index 00000000..a2544a18
--- /dev/null
+++ b/sale_timesheet_manager/views/project_views.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sale_timesheet_manager/views/time_manager_templates.xml b/sale_timesheet_manager/views/time_manager_templates.xml
new file mode 100644
index 00000000..07972a8e
--- /dev/null
+++ b/sale_timesheet_manager/views/time_manager_templates.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sale_timesheet_manager/views/web_assets.xml b/sale_timesheet_manager/views/web_assets.xml
new file mode 100644
index 00000000..0a407a33
--- /dev/null
+++ b/sale_timesheet_manager/views/web_assets.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file