From 2aa0bff4d849954ea02cb4e1f8b0c46ec348aa93 Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 17 Jul 2025 10:44:00 +0100 Subject: [PATCH] Fix leave days calculation for workdays-only leaves submitted via the app --- .../controllers/rest_api_v2/leave.py | 74 ++++++++++++++++++- odex25_mobile/odex_mobile/i18n/ar_001.po | 10 ++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/odex25_mobile/odex_mobile/controllers/rest_api_v2/leave.py b/odex25_mobile/odex_mobile/controllers/rest_api_v2/leave.py index b2fb5bdc0..53762c663 100644 --- a/odex25_mobile/odex_mobile/controllers/rest_api_v2/leave.py +++ b/odex25_mobile/odex_mobile/controllers/rest_api_v2/leave.py @@ -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) diff --git a/odex25_mobile/odex_mobile/i18n/ar_001.po b/odex25_mobile/odex_mobile/i18n/ar_001.po index 8c7b3e287..a49da4a9b 100644 --- a/odex25_mobile/odex_mobile/i18n/ar_001.po +++ b/odex25_mobile/odex_mobile/i18n/ar_001.po @@ -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 @@ -2383,4 +2385,10 @@ msgstr "ساعات السماحية بعد الدوام" #. module: odex_mobile #: model:ir.model.fields,field_description:odex_mobile.field_resource_calendar__grace_hour_before_work msgid "Grace Hours Before Work" -msgstr "ساعات السماحية قبل الدوم" \ No newline at end of file +msgstr "ساعات السماحية قبل الدوم" + +#. module: odex_mobile +#: code:addons/odex_mobile/controllers/rest_api_v2/leave.py:0 +#, python-format +msgid "Holiday Calculated Successfully" +msgstr "تم حساب عدد أيام الإجازة بنجاح" \ No newline at end of file