# -*- coding: utf-8 -*- from datetime import timedelta from dateutil.relativedelta import relativedelta from odoo import api, fields, models, _ from odoo.exceptions import UserError class HrHolidaySummaryReport(models.AbstractModel): _inherit = "report.hr_holidays.report_holidayssummary" def _get_header_info(self, start_date, end_date, holiday_type): st_date = fields.Date.from_string(start_date) end_date_ = ( fields.Date.from_string(end_date) if end_date else fields.Date.from_string(start_date + relativedelta(days=59)) ) return { "start_date": fields.Date.to_string(st_date), "end_date": fields.Date.to_string(end_date_), "holiday_type": "Confirmed and Approved" if holiday_type == "both" else holiday_type, } def _get_months(self, start_date, end_date): # it works for geting month name between two dates. res = [] start_date = fields.Date.from_string(start_date) # end_date = start_date + relativedelta(days=59) end_date_ = ( fields.Date.from_string(end_date) if end_date else fields.Date.from_string(start_date + relativedelta(days=59)) ) while start_date <= end_date_: last_date = start_date + relativedelta(day=1, months=+1, days=-1) if last_date > end_date_: last_date = end_date_ month_days = (last_date - start_date).days + 1 res.append({"month_name": start_date.strftime("%B"), "days": month_days}) start_date += relativedelta(day=1, months=+1) return res def _get_day(self, start_date, end_date): res = [] start_date = fields.Date.from_string(start_date) end_date_ = fields.Date.from_string(end_date) for x in range((end_date_ - start_date).days + 1): color = "#ababab" if self._date_is_day_off(start_date) else "" res.append( { "day_str": start_date.strftime("%a"), "day": start_date.day, "color": color, } ) start_date = start_date + relativedelta(days=1) return res def _get_data_from_report(self, data): res = [] Employee = self.env["hr.employee"] if "depts" in data: for department in self.env["hr.department"].browse(data["depts"]): res.append( { "dept": department.name, "data": [], "color": self._get_day(data["date_from"], data["date_to"]), } ) for emp in Employee.search([("department_id", "=", department.id)]): res[len(res) - 1]["data"].append( { "emp": emp.name, "display": self._get_leaves_summary( data["date_from"], data["date_to"], emp.id, data["holiday_type"], ), "sum": self.sum, } ) elif "emp" in data: res.append({"data": []}) for emp in Employee.browse(data["emp"]): res[0]["data"].append( { "emp": emp.name, "display": self._get_leaves_summary( data["date_from"], data["date_to"], emp.id, data["holiday_type"], ), "sum": self.sum, } ) return res def _get_leaves_summary(self, start_date, end_date, empid, holiday_type): res = [] count = 0 start_date = fields.Date.from_string(start_date) end_date_ = ( fields.Date.from_string(end_date) if end_date else fields.Date.from_string(start_date + relativedelta(days=59)) ) for index in range((end_date_ - start_date).days + 1): current = start_date + timedelta(index) res.append({"day": current.day, "color": ""}) if self._date_is_day_off(current): res[index]["color"] = "#ababab" # count and get leave summary details. holiday_type = ( ["confirm", "validate"] if holiday_type == "both" else ["confirm"] if holiday_type == "Confirmed" else ["validate"] ) holidays = self.env["hr.leave"].search( [ ("employee_id", "=", empid), ("state", "in", holiday_type), ("date_from", "<=", str(end_date_)), ("date_to", ">=", str(start_date)), ] ) for holiday in holidays: # Convert date to user timezone, otherwise the report will not be consistent with the # value displayed in the interface. date_from = fields.Datetime.from_string(holiday.date_from) date_from = fields.Datetime.context_timestamp(holiday, date_from).date() date_to = fields.Datetime.from_string(holiday.date_to) date_to = fields.Datetime.context_timestamp(holiday, date_to).date() for index in range(0, ((date_to - date_from).days + 1)): if date_from >= start_date and date_from <= end_date_: res[(date_from - start_date).days][ "color" ] = holiday.holiday_status_id.color_name date_from += timedelta(1) count += holiday.number_of_days self.sum = count return res @api.model def _get_report_values(self, docids, data=None): if not data.get("form"): raise UserError( _("Form content is missing, this report cannot be printed.") ) holidays_report = self.env["ir.actions.report"]._get_report_from_name( "hr_holidays.report_holidayssummary" ) holidays = self.env["hr.leave"].browse(self.ids) return { "doc_ids": self.ids, "doc_model": holidays_report.model, "docs": holidays, "get_header_info": self._get_header_info( data["form"]["date_from"], data["form"]["date_to"], data["form"]["holiday_type"], ), "get_day": self._get_day( data["form"]["date_from"], data["form"]["date_to"] ), "get_months": self._get_months( data["form"]["date_from"], data["form"]["date_to"] ), "get_data_from_report": self._get_data_from_report(data["form"]), "get_holidays_status": self._get_holidays_status(), }