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 re
import werkzeug import werkzeug
from odoo import http, tools,fields 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.http import request, Response
from odoo.addons.auth_signup.models.res_users import SignupError from odoo.addons.auth_signup.models.res_users import SignupError
from odoo.exceptions import UserError ,AccessError, ValidationError from odoo.exceptions import UserError ,AccessError, ValidationError
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import math
import base64 import base64
from ...validator import validator from ...validator import validator
from ...http_helper import http_helper from ...http_helper import http_helper
@ -63,6 +63,38 @@ class LeaveController(http.Controller):
'issuing_ticket': hol.issuing_ticket}) 'issuing_ticket': hol.issuing_ticket})
return value 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']) @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): def get_leaves(self, approvel=None, done=None, page=None, **kw):
http_method, body, headers, token = http_helper.parse_request() http_method, body, headers, token = http_helper.parse_request()
@ -494,3 +526,41 @@ class LeaveController(http.Controller):
_logger.error(str(e)) _logger.error(str(e))
message = validator.get_server_error(e, user) message = validator.get_server_error(e, user)
return http_helper.errcode(code=403, message=message) 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/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 #: 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/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 #: 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
@ -2383,4 +2385,10 @@ msgstr "ساعات السماحية بعد الدوام"
#. module: odex_mobile #. module: odex_mobile
#: model:ir.model.fields,field_description:odex_mobile.field_resource_calendar__grace_hour_before_work #: model:ir.model.fields,field_description:odex_mobile.field_resource_calendar__grace_hour_before_work
msgid "Grace Hours Before Work" msgid "Grace Hours Before Work"
msgstr "ساعات السماحية قبل الدوم" msgstr "ساعات السماحية قبل الدوم"
#. module: odex_mobile
#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0
#, python-format
msgid "Holiday Calculated Successfully"
msgstr "تم حساب عدد أيام الإجازة بنجاح"