Leaves Timesheets Management

This commit is contained in:
pranaysaidurga 2026-05-25 16:38:40 +05:30
parent 5460f6c207
commit 96493be796
7 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1 @@
from . import models

View File

@ -0,0 +1,22 @@
{
'name': 'Leaves Timesheets Extended',
'version': '18.0.1.0.0',
'category': 'Human Resources',
'summary': 'Integrate Leaves with Timesheets',
'author': 'Srivyn Platforms',
'license': 'LGPL-3',
'depends': [
'hr_holidays',
'hr_timesheet',
'project',
],
'data': [
'data/project_task_data.xml',
'views/hr_leave_views.xml',
],
'installable': True,
'application': False,
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Default Internal Project -->
<record id="project_internal_leave" model="project.project">
<field name="name">Internal Project</field>
<!-- REQUIRED FIELD -->
<field name="user_id" ref="base.user_admin"/>
<field name="allow_timesheets">True</field>
</record>
<!-- Default Leave Task -->
<record id="task_leave_management" model="project.task">
<field name="name">Leaves Management</field>
<field name="project_id"
ref="project_internal_leave"/>
<!-- OPTIONAL BUT RECOMMENDED -->
<field name="user_ids"
eval="[(4, ref('base.user_admin'))]"/>
</record>
</odoo>

View File

@ -0,0 +1 @@
from . import hr_leave

View File

@ -0,0 +1,80 @@
from odoo import models, fields, api
class HrLeave(models.Model):
_inherit = 'hr.leave'
project_id = fields.Many2one(
'project.project',
string='Project'
)
task_id = fields.Many2one(
'project.task',
string='Task'
)
timesheet_line_id = fields.Many2one(
'account.analytic.line',
string='Timesheet Entry',
readonly=True,
copy=False
)
# CREATE TIMESHEET ON APPROVAL
def action_validate(self, check_state=True):
res = super().action_validate(check_state=check_state)
default_project = self.env.ref(
'leaves_timesheets_extended.project_internal_leave'
)
default_task = self.env.ref(
'leaves_timesheets_extended.task_leave_management'
)
for leave in self:
# Prevent duplicate creation
if leave.timesheet_line_id:
continue
project = leave.project_id or default_project
task = leave.task_id or default_task
# Hours Calculation
if leave.request_unit_half:
hours = 4
else:
hours = leave.number_of_days * 8
analytic_line = self.env[
'account.analytic.line'
].create({
'name': f"Leave: {leave.holiday_status_id.name}",
'employee_id': leave.employee_id.id,
'user_id': leave.employee_id.user_id.id,
'project_id': project.id,
'task_id': task.id,
'unit_amount': hours,
'date': leave.request_date_from,
'company_id': leave.company_id.id,
})
leave.timesheet_line_id = analytic_line.id
return res
# DELETE TIMESHEET ON REFUSE
def action_refuse(self):
res = super().action_refuse()
for leave in self:
if leave.timesheet_line_id:
leave.timesheet_line_id.unlink()
leave.timesheet_line_id = False
return res

View File

@ -0,0 +1 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_hr_leave_form_inherit_timesheet"
model="ir.ui.view">
<field name="name">
hr.leave.form.inherit.timesheet
</field>
<field name="model">hr.leave</field>
<field name="inherit_id"
ref="hr_holidays.hr_leave_view_form"/>
<field name="arch" type="xml">
<xpath expr="//group" position="inside">
<field name="project_id"/>
<field name="task_id"
domain="[('project_id', '=', project_id)]"/>
</xpath>
</field>
</record>
</odoo>