diff --git a/addons/project_timesheet_holidays/__init__.py b/addons/project_timesheet_holidays/__init__.py
new file mode 100644
index 00000000000..dc5e6b693d1
--- /dev/null
+++ b/addons/project_timesheet_holidays/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import models
diff --git a/addons/project_timesheet_holidays/__manifest__.py b/addons/project_timesheet_holidays/__manifest__.py
new file mode 100644
index 00000000000..73f0ac35342
--- /dev/null
+++ b/addons/project_timesheet_holidays/__manifest__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+ 'name': 'Timesheet when on Leaves',
+ 'version': '1.0',
+ 'category': 'Human Resources',
+ 'summary': 'Schedule timesheet when on leaves',
+ 'description': """
+Bridge module to integrate holidays in timesheet
+================================================
+
+This module allows to automatically log timesheets when employees are
+on leaves. Project and task can be configured company-wide.
+ """,
+ 'depends': ['hr_timesheet', 'hr_holidays'],
+ 'data': [
+ 'views/res_config_views.xml',
+ 'views/hr_holidays_views.xml',
+ ],
+ 'demo': [],
+ 'installable': True,
+ 'auto_install': True,
+}
diff --git a/addons/project_timesheet_holidays/models/__init__.py b/addons/project_timesheet_holidays/models/__init__.py
new file mode 100644
index 00000000000..59576c427c4
--- /dev/null
+++ b/addons/project_timesheet_holidays/models/__init__.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import account_analytic
+from . import hr_holidays
+from . import res_company
+from . import res_config
diff --git a/addons/project_timesheet_holidays/models/account_analytic.py b/addons/project_timesheet_holidays/models/account_analytic.py
new file mode 100644
index 00000000000..b0472a515be
--- /dev/null
+++ b/addons/project_timesheet_holidays/models/account_analytic.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+from odoo.exceptions import UserError
+
+
+class AccountAnalyticLine(models.Model):
+ _inherit = 'account.analytic.line'
+
+ holiday_id = fields.Many2one("hr.holidays", string='Leave Request')
+
+ @api.multi
+ def unlink(self):
+ if any(line.holiday_id for line in self):
+ raise UserError(_('You cannot delete timesheet lines attached to a leaves. Please cancel the leaves instead.'))
+ return super(AccountAnalyticLine, self).unlink()
diff --git a/addons/project_timesheet_holidays/models/hr_holidays.py b/addons/project_timesheet_holidays/models/hr_holidays.py
new file mode 100644
index 00000000000..c69cda4f2ff
--- /dev/null
+++ b/addons/project_timesheet_holidays/models/hr_holidays.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models
+
+
+class HolidaysType(models.Model):
+ _inherit = "hr.holidays.status"
+
+ timesheet_generate = fields.Boolean('Generate Timesheet', help="If checked, when validating a leave, timesheet will be generated in the Vacation Project of the company.")
+ timesheet_project_id = fields.Many2one('project.project', string="Internal Project", help="The project will contain the timesheet generated when a leave is validated.")
+ timesheet_task_id = fields.Many2one('project.task', string="Internal Task for timesheet", domain="[('project_id', '=', timesheet_project_id)]")
+
+ @api.onchange('timesheet_generate')
+ def _onchange_timesheet_generate(self):
+ if self.timesheet_generate:
+ company = self.company_id if self.company_id else self.env.user.company_id
+ self.timesheet_project_id = company.leave_timesheet_project_id
+ self.timesheet_task_id = company.leave_timesheet_task_id
+ else:
+ self.timesheet_project_id = False
+ self.timesheet_task_id = False
+
+
+class Holidays(models.Model):
+ _inherit = "hr.holidays"
+
+ timesheet_ids = fields.One2many('account.analytic.line', 'holiday_id', string="Analytic Lines")
+
+ def _validate_leave_request(self):
+ """ Timesheet will be generated on leave validation only if a timesheet_project_id and a
+ timesheet_task_id are set on the corresponding leave type. The generated timesheet will
+ be attached to this project/task.
+ """
+ # create the timesheet on the vacation project
+ for holiday in self.filtered(
+ lambda request: request.type == 'remove' and
+ request.holiday_type == 'employee' and
+ request.holiday_status_id.timesheet_project_id and
+ request.holiday_status_id.timesheet_task_id):
+ holiday_project = holiday.holiday_status_id.timesheet_project_id
+ holiday_task = holiday.holiday_status_id.timesheet_task_id
+
+ work_hours_data = [item for item in holiday.employee_id.iter_work_hours_count(fields.Datetime.from_string(holiday.date_from), fields.Datetime.from_string(holiday.date_to))]
+ for index, (day_date, work_hours_count) in enumerate(work_hours_data):
+ self.env['account.analytic.line'].create({
+ 'name': "%s (%s/%s)" % (holiday.name, index + 1, len(work_hours_data)),
+ 'project_id': holiday_project.id,
+ 'task_id': holiday_task.id,
+ 'account_id': holiday_project.analytic_account_id.id,
+ 'unit_amount': work_hours_count,
+ 'user_id': holiday.employee_id.user_id.id,
+ 'date': fields.Date.to_string(day_date),
+ 'holiday_id': holiday.id,
+ })
+
+ return super(Holidays, self)._validate_leave_request()
+
+ @api.multi
+ def action_refuse(self):
+ """ Remove the timesheets linked to the refused holidays """
+ result = super(Holidays, self).action_refuse()
+ self.mapped('timesheet_ids').unlink()
+ return result
diff --git a/addons/project_timesheet_holidays/models/res_company.py b/addons/project_timesheet_holidays/models/res_company.py
new file mode 100644
index 00000000000..3d21974573c
--- /dev/null
+++ b/addons/project_timesheet_holidays/models/res_company.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+
+
+class Company(models.Model):
+ _inherit = 'res.company'
+
+ leave_timesheet_project_id = fields.Many2one(
+ 'project.project', string="Internal Project",
+ help="Default project value for timesheet generated from leave type.")
+ leave_timesheet_task_id = fields.Many2one(
+ 'project.task', string="Leave Task",
+ domain="[('project_id', '=', leave_timesheet_project_id)]")
+
+ def _init_column(self, name):
+ super(Company, self)._init_column(name)
+
+ if name == 'leave_timesheet_project_id':
+ self.search([('leave_timesheet_project_id', '=', False)])._create_leave_project_task()
+
+ @api.model
+ def create(self, values):
+ company = super(Company, self).create(values)
+ company._create_leave_project_task()
+ return company
+
+ def _create_leave_project_task(self):
+ for company in self:
+ if not company.leave_timesheet_project_id:
+ project = self.env['project.project'].create({
+ 'name': _('Internal Project'),
+ 'allow_timesheets': True,
+ 'active': False,
+ 'company_id': company.id,
+ })
+ company.write({
+ 'leave_timesheet_project_id': project.id,
+ })
+ if not company.leave_timesheet_task_id:
+ task = self.env['project.task'].create({
+ 'name': _('Leaves'),
+ 'project_id': company.leave_timesheet_project_id.id,
+ 'active': False,
+ })
+ company.write({
+ 'leave_timesheet_task_id': task.id,
+ })
diff --git a/addons/project_timesheet_holidays/models/res_config.py b/addons/project_timesheet_holidays/models/res_config.py
new file mode 100644
index 00000000000..d1603fb007f
--- /dev/null
+++ b/addons/project_timesheet_holidays/models/res_config.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class TimesheetConfig(models.TransientModel):
+ _inherit = 'hr.timesheet.config.settings'
+
+ leave_timesheet_project_id = fields.Many2one(related='company_id.leave_timesheet_project_id', string="Internal Project")
+ leave_timesheet_task_id = fields.Many2one(related='company_id.leave_timesheet_task_id', string="Leave Task")
diff --git a/addons/project_timesheet_holidays/views/hr_holidays_views.xml b/addons/project_timesheet_holidays/views/hr_holidays_views.xml
new file mode 100644
index 00000000000..ca1ae705bda
--- /dev/null
+++ b/addons/project_timesheet_holidays/views/hr_holidays_views.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ hr.holidays.status.form
+ hr.holidays.status
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/project_timesheet_holidays/views/res_config_views.xml b/addons/project_timesheet_holidays/views/res_config_views.xml
new file mode 100644
index 00000000000..5c29c1d31f3
--- /dev/null
+++ b/addons/project_timesheet_holidays/views/res_config_views.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ hr.timesheet.config.settings.view.form
+ hr.timesheet.config.settings
+
+
+
+
+
+
+
+
+