Fix leave days calculation for workdays-only leaves submitted via the app

This commit is contained in:
younes 2025-07-17 10:44:00 +01:00
parent 452eb2642d
commit 2aa0bff4d8
2 changed files with 81 additions and 3 deletions

View File

@ -2,12 +2,12 @@
import re
import werkzeug
from odoo import http, tools,fields
from datetime import datetime, tzinfo, timedelta
from datetime import datetime, tzinfo, timedelta, date
from odoo.http import request, Response
from odoo.addons.auth_signup.models.res_users import SignupError
from odoo.exceptions import UserError ,AccessError, ValidationError
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import math
import base64
from ...validator import validator
from ...http_helper import http_helper
@ -63,6 +63,38 @@ class LeaveController(http.Controller):
'issuing_ticket': hol.issuing_ticket})
return value
def _get_number_of_days(self, date_from, date_to, employee_id, official_event=True, working_days=False):
""" Returns a float equals to the timedelta between two dates given as string."""
from_dt = fields.Datetime.from_string(date_from)
to_dt = fields.Datetime.from_string(date_to)
if not employee_id: return 0.0
employee = http.request.env['hr.employee'].browse(employee_id)
time_delta = to_dt - from_dt
time_delta = math.ceil(time_delta.days + 1 + float(time_delta.seconds) / 86400)
if not official_event or working_days:
hlist = []
for i in range((to_dt - from_dt).days + 1): hlist.append(from_dt.date() + timedelta(days=i))
if official_event is False:
dlist = []
hr_holiday_officials = http.request.env['hr.holiday.officials'].search([('active', '=', True), ('state', '=', 'confirm'),
('date_from', '<=', date_to),
('date_to', '>=', date_from)])
for event in hr_holiday_officials:
if event.religion and employee_id and employee.religion != event.religion: continue
edate_from = datetime.strptime(str(event.date_from), '%Y-%m-%d').date()
dlt = datetime.strptime(str(event.date_to), '%Y-%m-%d').date() - edate_from
for i in range(dlt.days + 1): dlist.append(edate_from + timedelta(days=i))
time_delta = len(list(set(hlist) - set(dlist)))
self.official_holiday_days = len([rec for rec in dlist if rec >= from_dt.date() and rec <= to_dt.date()])
if working_days:
wkends = employee.resource_calendar_id.full_day_off or employee.resource_calendar_id.shift_day_off
wknd_days = [d.name.lower() for d in wkends]
rlist = official_event is False and dlist and list(set(hlist) - set(dlist)) or hlist
for dt in rlist:
if dt.strftime('%A').lower() in wknd_days: time_delta -= 1
return time_delta
@http.route(['/rest_api/v2/leaves'], type='http', auth='none', csrf=False, methods=['GET'])
def get_leaves(self, approvel=None, done=None, page=None, **kw):
http_method, body, headers, token = http_helper.parse_request()
@ -494,3 +526,41 @@ class LeaveController(http.Controller):
_logger.error(str(e))
message = validator.get_server_error(e, user)
return http_helper.errcode(code=403, message=message)
@http.route(['/rest_api/v2/leaves/no_days_holiday'], type='http', auth='none', csrf=False, methods=['GET'])
def get_leave_no_holiday(self, **kw):
http_method, body, headers, token = http_helper.parse_request()
result = validator.verify_token(token)
if not result['status']:
return http_helper.errcode(code=result['code'], message=result['message'])
user = validator.verify(token)
if not user:
return http_helper.response(code=400, message=_(
"You are not allowed to perform this operation. please check with one of your team admins"),
success=False)
employee = http.request.env['hr.employee'].search([('user_id', '=', user.id)], limit=1)
if not employee:
return http_helper.response(code=400, message=_(
"You Have issue in your employee profile. please check with one of your team admins"), success=False)
if not body.get('date_from') or not body.get('date_to') or not body.get('type_id'):
return http_helper.response(code=400, message=_("Enter All required Dates for Leave request"),
success=False)
try:
date_from = body['date_from']
date_to = body['date_to']
holiday_status_id = int(body['type_id'])
holiday_statu = http.request.env['hr.holidays.status'].search([('id', '=', holiday_status_id)])
days = self._get_number_of_days(date_from, date_to, employee.id,
holiday_statu.official_holidays,holiday_statu.working_days)
data = {
'number_of_leave_days': days,
}
return http_helper.response(message=_("Holiday Calculated Successfully"), data=data)
except Exception as e:
http.request._cr.rollback()
_logger.error(str(e))
message = validator.get_server_error(e, user)
return http_helper.errcode(code=403, message=message)

View File

@ -1926,6 +1926,7 @@ msgstr ""
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
@ -2054,6 +2055,7 @@ msgstr "لا يمكنك تنفيذ هذه العملية. يرجى مراجعة
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
#: code:addons/odex_mobile/controllers/rest_api_v2/loan.py:0
@ -2384,3 +2386,9 @@ msgstr "ساعات السماحية بعد الدوام"
#: model:ir.model.fields,field_description:odex_mobile.field_resource_calendar__grace_hour_before_work
msgid "Grace Hours Before Work"
msgstr "ساعات السماحية قبل الدوم"
#. module: odex_mobile
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#, python-format
msgid "Holiday Calculated Successfully"
msgstr "تم حساب عدد أيام الإجازة بنجاح"