[T-4819] [FIX] Update massive approve method

Merged Facundo Barral requested to merge T-4819 into 15.0-stage
Compare and
2 files
+ 3
311
Preferences
File browser
Compare changes
+ 0
308
from odoo import _, api, fields, models
import datetime
from dateutil.relativedelta import relativedelta
from odoo.exceptions import ValidationError
from odoo.addons.hr_payroll_base_config.models.antique_recognized import (
AntiqueRecognized,
)
from odoo.addons.resource.models.resource import HOURS_PER_DAY
import logging
_logger = logging.getLogger(__name__)
class HolidaysAssignmentNotify(models.TransientModel):
_name = "holidays.assignment.notify"
message = fields.Html("Notify Message")
def action_ok(self):
"""close wizard"""
return {"type": "ir.actions.act_window_close"}
class HrLeave(models.Model):
_inherit = "hr.leave"
def approve_selected_leaves(self):
not_approved = self.filtered(lambda r: r.state in ("draft", "confirm"))
for leave in not_approved:
leave.action_approve()
class HrLeaveAllocation(models.Model):
_inherit = "hr.leave.allocation"
def approve_selected_allocation(self):
not_approved = self.filtered(lambda r: r.state in ("draft", "confirm"))
for allocation in not_approved:
allocation.action_refuse()
class HrEmployee(models.TransientModel):
_name = "holidays.assignment"
holiday_status_id = fields.Many2one(
"hr.leave.type",
string="Type of absence",
domain=[("type", "=", "holidays")],
required=True,
)
holiday_leaves = fields.Many2one("hr.leave.allocation")
holiday_recompute = fields.Boolean(
string="Check for missing assignations",
help="Go back to review the employees who already have this assignment to check if there are days remaining to assign. \nAssignments will be created with [To Approve] status.",
)
def create_holidays_assignment(self):
val_err = _("All contract already assigned")
contracts_ids = self.env["hr.contract"].search(
[("state", "=", "open"), ("active", "=", True)]
)
total_assignment = (
self.env["hr.leave.allocation"]
.search([("holiday_status_id", "=", self.holiday_status_id.id)])
.mapped(lambda x: x.employee_id.id)
)
end_year = datetime.date(year=self.holiday_status_id.sequence, day=31, month=12)
total = []
assignments = 0
if not self.holiday_recompute:
for contract_employee in contracts_ids:
if contract_employee.employee_id.id not in total_assignment:
total.append(contract_employee)
else:
total = contracts_ids
if total:
for contract in total:
this_employee = contract.employee_id.id
if not this_employee:
continue
antique = AntiqueRecognized(this_employee, end_year, self.env)
days_antique = antique.antique_recognized()
total_months = int(days_antique / 30)
if total_months < 6:
days_antique = antique.antique_recognized(6) # Exclude sundays
number_of_days_display = self.holidays_cases(total_months, days_antique)
name = (
_("Automatic holiday assignment in Year: %s")
% self.holiday_status_id.sequence
)
if self.holiday_recompute:
actual_assignment = self.env["hr.leave.allocation"].search(
[
("holiday_status_id", "=", self.holiday_status_id.id),
("employee_id.id", "=", this_employee),
("state", "in", ["validate", "confirm", "validate1"]),
]
)
assigned_days = sum(
int(record.number_of_days) for record in actual_assignment
)
if assigned_days < number_of_days_display:
name = _("Remaining holiday assignment in Year: %s (%s/%s)") % (
self.holiday_status_id.sequence,
assigned_days,
number_of_days_display,
)
# Remove already assigned days and get remainings
number_of_days_display -= assigned_days or 0
# weekend_qty = int(number_of_days_display / 7)
if number_of_days_display >= 1:
note = _(
"Employee seniority days computed for this assignation: %s\nDate used for the calculation of seniority: %s"
) % (days_antique, end_year)
assignments += 1
_logger.info("Assign Leave to employee with ID: %s" % this_employee)
self.holiday_leaves.create(
{
"name": name,
"holiday_status_id": self.holiday_status_id.id,
"number_of_days": number_of_days_display,
"holiday_type": "employee",
"employee_id": this_employee,
"state": self.holiday_recompute and "confirm" or "validate",
# "weekend_qty": weekend_qty,
"notes": note,
}
)
else:
raise ValidationError(val_err)
notify_message = (
_("Holiday assignment was made to a total of: {0} employees\n\n")
).format(assignments)
return {
"name": _("Holidays assignment"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "holidays.assignment.notify",
"res_id": self.env["holidays.assignment.notify"]
.create({"message": notify_message})
.id,
"target": "new",
}
def holidays_cases(self, n, d):
if n < 6:
return int(d / 20)
elif n < 60:
return 14
elif n < 120:
return 21
elif n < 240:
return 28
else:
return 35
class MassiveLeaveWizard(models.TransientModel):
_name = "massive.leave.assignment"
holiday_status_id = fields.Many2one(
"hr.leave.type", string="Type of absence", required=True
)
start_date = fields.Date("Start Date", required=True)
end_date = fields.Date("End Date", required=True)
employees = fields.Many2many(
string="Employees",
comodel_name="hr.employee",
domain=[("last_contract_id", "!=", False)],
)
description = fields.Char("Description")
hr_leaves = fields.Many2one("hr.leave")
def create_massive_leave(self):
errors_list = ""
created_leaves = []
df, dt = datetime.datetime.combine(
self.start_date, datetime.datetime.min.time()
), datetime.datetime.combine(self.end_date, datetime.datetime.max.time())
for emp in self.employees:
try:
with self.env.cr.savepoint():
new_leave = self.with_context(import_file=True).hr_leaves.create(
{
"holiday_status_id": self.holiday_status_id.id,
"holiday_type": "employee",
"employee_id": emp.id,
"request_date_from": self.start_date,
"request_date_to": self.end_date,
"date_from": df,
"date_to": dt,
"name": self.description,
}
)
# new_leave._onchange_request_parameters() # Update number_of_days correctly
# new_leave._compute_weekend_qty() # Update weekends days
created_leaves.append(new_leave)
_logger.info("Created leave to employee with ID: %s" % emp.id)
self.env.cr.commit()
except ValidationError as e:
errors_list += emp.name + ": " + str(e.name) + "\n\n"
self.env.cr.rollback()
notify_message = (
_("Absence assignment was made to a total of: {0} of {1} employees\n\n")
).format(len(created_leaves), len(self.employees))
if len(errors_list) > 0:
notify_message += _(
"Errors occurred and the following assignments could not be performed correctly:\n\n{}"
).format(errors_list)
return {
"name": _("Mass assignment of absences"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "holidays.assignment.notify",
"res_id": self.env["holidays.assignment.notify"]
.create({"message": notify_message})
.id,
"target": "new",
}
class LicenseAssignmentWizard(models.TransientModel):
_name = "massive.license.assignment"
description = fields.Char("Description")
approved = fields.Boolean("Approved")
leave_types = fields.Many2many(
string="Licenses",
comodel_name="hr.leave.type",
domain=[
("name", "ilike", "LIC"),
("allocation_max", "!=", False),
("allocation_max", ">", 0),
],
)
def create_massive_license(self):
errors_list = ""
created_licenses = []
contracts_ids = self.env["hr.contract"].search(
[("state", "=", "open"), ("active", "=", True)]
)
for contract in contracts_ids:
emp = contract.employee_id
this_employee = emp.id
if not this_employee:
continue
for lic in self.leave_types:
try:
lic_days = lic.get_days(this_employee)[lic.id]
if not lic_days:
continue
days_to_assign = lic.allocation_max - lic_days["remaining_leaves"]
if days_to_assign < 1 or this_employee in created_licenses:
continue
created_licenses.append(this_employee)
hours_per_day = (
emp.resource_calendar_id.hours_per_day or HOURS_PER_DAY
)
total_days = (
(days_to_assign)
if (lic.request_unit == "day")
else (days_to_assign / hours_per_day)
)
self.env["hr.leave.allocation"].create(
{
"holiday_type": "employee",
"employee_id": this_employee,
"holiday_status_id": lic.id,
"state": ("validate" if self.approved else "confirm"),
"number_of_days": total_days,
"name": (
self.description or _("Massive license assignment")
),
}
)
except ValidationError as e:
errors_list += emp.name + ": " + str(e.name) + "\n\n"
notify_message = (
_("Licenses assignment was made to a total of: {0} of {1} employees\n\n")
).format(len(created_licenses), len(contracts_ids))
if len(errors_list) > 0:
notify_message += _(
"Errors occurred and the following assignments could not be performed correctly:\n\n{}"
).format(errors_list)
return {
"name": _("Massive license assignment"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "holidays.assignment.notify",
"res_id": self.env["holidays.assignment.notify"]
.create({"message": notify_message})
.id,
"target": "new",
}