173 lines
8.7 KiB
Python
173 lines
8.7 KiB
Python
from logging import exception
|
|
|
|
from odoo import api, models, _, fields
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tools.misc import format_date
|
|
from datetime import datetime
|
|
|
|
class HRLeave(models.Model):
|
|
_inherit = "hr.leave"
|
|
|
|
def flutter_check_overlap_constrain(self,employee_id, to_date, from_date, fetched_leave_id=None):
|
|
if self.env.context.get('leave_skip_date_check', False):
|
|
return
|
|
date_from = datetime.fromisoformat(from_date).replace(hour=0, minute=0, second=0)
|
|
date_to = datetime.fromisoformat(to_date).replace(hour=23, minute=59, second=59)
|
|
employee_id = int(employee_id)
|
|
if fetched_leave_id and fetched_leave_id > 0:
|
|
all_leaves = self.search([
|
|
('date_from', '<', date_to),
|
|
('date_to', '>', date_from),
|
|
('employee_id', 'in', [employee_id]),
|
|
('id','!=', fetched_leave_id),
|
|
('state', 'not in', ['cancel', 'refuse']),
|
|
])
|
|
|
|
domain = [
|
|
('employee_id', '=', employee_id),
|
|
('date_from', '<', date_to),
|
|
('date_to', '>', date_from),
|
|
('id', '!=', fetched_leave_id),
|
|
('state', 'not in', ['cancel', 'refuse']),
|
|
]
|
|
else:
|
|
all_leaves = self.search([
|
|
('date_from', '<', date_to),
|
|
('date_to', '>', date_from),
|
|
('employee_id', 'in', [employee_id]),
|
|
('state', 'not in', ['cancel', 'refuse']),
|
|
])
|
|
domain = [
|
|
('employee_id', '=', employee_id),
|
|
('date_from', '<', date_to),
|
|
('date_to', '>', date_from),
|
|
('state', 'not in', ['cancel', 'refuse']),
|
|
]
|
|
|
|
|
|
conflicting_holidays = all_leaves.filtered_domain(domain)
|
|
|
|
if conflicting_holidays:
|
|
conflicting_holidays_list = []
|
|
# Do not display the name of the employee if the conflicting holidays have an employee_id.user_id equivalent to the user id
|
|
holidays_only_have_uid = bool(employee_id)
|
|
holiday_states = dict(conflicting_holidays.fields_get(allfields=['state'])['state']['selection'])
|
|
for conflicting_holiday in conflicting_holidays:
|
|
conflicting_holiday_data = {}
|
|
conflicting_holiday_data['employee_name'] = conflicting_holiday.employee_id.name
|
|
conflicting_holiday_data['date_from'] = format_date(self.env,
|
|
min(conflicting_holiday.mapped('date_from')))
|
|
conflicting_holiday_data['date_to'] = format_date(self.env,
|
|
min(conflicting_holiday.mapped('date_to')))
|
|
conflicting_holiday_data['state'] = holiday_states[conflicting_holiday.state]
|
|
if conflicting_holiday.employee_id.user_id.id != self.env.uid:
|
|
holidays_only_have_uid = False
|
|
if conflicting_holiday_data not in conflicting_holidays_list:
|
|
conflicting_holidays_list.append(conflicting_holiday_data)
|
|
if not conflicting_holidays_list:
|
|
return
|
|
conflicting_holidays_strings = []
|
|
if holidays_only_have_uid:
|
|
for conflicting_holiday_data in conflicting_holidays_list:
|
|
conflicting_holidays_string = _('from %(date_from)s to %(date_to)s - %(state)s',
|
|
date_from=conflicting_holiday_data['date_from'],
|
|
date_to=conflicting_holiday_data['date_to'],
|
|
state=conflicting_holiday_data['state'])
|
|
conflicting_holidays_strings.append(conflicting_holidays_string)
|
|
error = """\
|
|
You've already booked time off which overlaps with this period:
|
|
%s
|
|
Attempting to double-book your time off won't magically make your vacation 2x better!
|
|
""".join(conflicting_holidays_strings)
|
|
return error
|
|
for conflicting_holiday_data in conflicting_holidays_list:
|
|
conflicting_holidays_string = "\n" + _(
|
|
'%(employee_name)s - from %(date_from)s to %(date_to)s - %(state)s',
|
|
employee_name=conflicting_holiday_data['employee_name'],
|
|
date_from=conflicting_holiday_data['date_from'],
|
|
date_to=conflicting_holiday_data['date_to'],
|
|
state=conflicting_holiday_data['state'])
|
|
conflicting_holidays_strings.append(conflicting_holidays_string)
|
|
error = "An employee already booked time off which overlaps with this period:%s","".join(conflicting_holidays_strings)
|
|
return error
|
|
|
|
@api.model
|
|
def calculate_leave_duration(self, date_from, date_to, employee_id):
|
|
"""
|
|
Calculate the number of days and hours for the given date range and employee.
|
|
"""
|
|
employee = self.env['hr.employee'].browse(employee_id)
|
|
if not employee:
|
|
return {'error': 'Employee not found'}
|
|
|
|
from_date = datetime.fromisoformat(date_from).replace(hour=0, minute=0, second=0)
|
|
to_date = datetime.fromisoformat(date_to).replace(hour=23, minute=59, second=59)
|
|
|
|
# Define a fake leave record to use _get_durations
|
|
leave_values = {
|
|
'employee_id': employee.id,
|
|
'date_from': fields.Datetime.from_string(from_date),
|
|
'date_to': fields.Datetime.from_string(to_date),
|
|
'holiday_status_id': self.env['hr.leave.type'].search([], limit=1).id,
|
|
# Replace with appropriate leave type ID
|
|
'resource_calendar_id': employee.resource_calendar_id.id,
|
|
}
|
|
leave = self.new(leave_values)
|
|
durations = leave._get_durations()
|
|
leave_id = list(durations.keys())[0]
|
|
days, hours = durations[leave_id]
|
|
|
|
return {
|
|
'days': float(days),
|
|
'hours': float(hours),
|
|
}
|
|
|
|
@api.model
|
|
def submit_leave_flutter_odoo(self,leave_request_data, existing_leave_id = None):
|
|
try:
|
|
date_from = datetime.fromisoformat(leave_request_data['date_from']).replace(hour=0, minute=0, second=0)
|
|
date_to = datetime.fromisoformat(leave_request_data['date_to']).replace(hour=23, minute=59, second=59)
|
|
if existing_leave_id and existing_leave_id > 0:
|
|
leave_id = self.env['hr.leave'].sudo().browse(existing_leave_id)
|
|
else:
|
|
leave_id = False
|
|
if leave_id:
|
|
leave_id.sudo().write({
|
|
'employee_id': leave_request_data['employee_id'],
|
|
'holiday_status_id': leave_request_data['holiday_status_id'],
|
|
'request_date_from': date_from.date(),
|
|
'request_date_to':date_to.date(),
|
|
'name': leave_request_data['description'],
|
|
'request_unit_half': leave_request_data['is_half_day'],
|
|
'request_date_from_period': 'pm' if leave_request_data['half_day_option'] == 'afternoon' else 'am',
|
|
})
|
|
leave = leave_id
|
|
else:
|
|
leave = self.env['hr.leave'].sudo().create({
|
|
'employee_id': leave_request_data['employee_id'],
|
|
'holiday_status_id': leave_request_data['holiday_status_id'],
|
|
'request_date_from': date_from.date(),
|
|
'request_date_to':date_to.date(),
|
|
'name':leave_request_data['description'],
|
|
'request_unit_half': leave_request_data['is_half_day'],
|
|
'request_date_from_period': 'pm' if leave_request_data['half_day_option'] == 'afternoon' else 'am',
|
|
})
|
|
attachment_ids = []
|
|
for attachment in leave_request_data['attachments']:
|
|
attachment_record = self.env['ir.attachment'].create({
|
|
'name': attachment['name'], # Attachment name
|
|
'datas': attachment['datas'], # Base64 encoded data
|
|
'res_model': 'hr.leave', # Model to link
|
|
'res_id': leave.id, # ID of the leave record
|
|
})
|
|
attachment_ids.append(attachment_record.id)
|
|
|
|
# Link the attachments to the leave record
|
|
if attachment_ids:
|
|
leave.supported_attachment_ids = [(6, 0, attachment_ids)]
|
|
|
|
leave._check_validity()
|
|
leave.state = 'confirm'
|
|
return {'status': 'success', 'leave_id': leave.id, 'message': ''}
|
|
except Exception as e:
|
|
return {'status': 'error','leave_id': '', 'message': str(e)} |