181 lines
7.0 KiB
Python
181 lines
7.0 KiB
Python
# -*- 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(),
|
|
}
|