# Copyright 2026 Criptomart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from markupsafe import Markup from odoo import _, api, fields, models from ..models.res_company import LEAVE_POLICY_SELECTION class HrTimesheetSheetDeleteWizard(models.TransientModel): _name = "hr_timesheet.sheet.delete.wizard" _description = "Delete Timesheet Sheets" sheet_ids = fields.Many2many( comodel_name="hr_timesheet.sheet", string="Timesheet Sheets", ) sheet_count = fields.Integer( string="Sheets", compute="_compute_delete_cascade_data", ) timesheet_count = fields.Integer( string="Timesheet Entries", compute="_compute_delete_cascade_data", ) timesheet_hours = fields.Float( string="Hours", compute="_compute_delete_cascade_data", ) invoiced_count = fields.Integer( string="Invoiced Entries", compute="_compute_delete_cascade_data", ) leave_policy = fields.Selection( selection=LEAVE_POLICY_SELECTION, string="Time Off Policy", compute="_compute_delete_cascade_data", ) leave_ids = fields.Many2many( comodel_name="hr.leave", relation="hr_timesheet_sheet_delete_wizard_leave_rel", string="Time Off To Cancel", compute="_compute_delete_cascade_data", ) leave_count = fields.Integer( string="Time Off Entries", compute="_compute_delete_cascade_data", ) leave_days = fields.Float( string="Days Restored", compute="_compute_delete_cascade_data", ) partial_leave_ids = fields.Many2many( comodel_name="hr.leave", relation="hr_timesheet_sheet_delete_wizard_partial_leave_rel", string="Time Off Beyond The Sheet Period", compute="_compute_delete_cascade_data", ) blocking_reason = fields.Text( string="Blocking Reason", compute="_compute_delete_cascade_data", ) summary_html = fields.Html( string="Summary", compute="_compute_delete_cascade_data", sanitize=False, ) @api.model def default_get(self, fields_list): res = super().default_get(fields_list) if self.env.context.get("active_model") == "hr_timesheet.sheet": res["sheet_ids"] = [(6, 0, self.env.context.get("active_ids") or [])] return res @api.depends("sheet_ids") def _compute_delete_cascade_data(self): for wizard in self: sheets = wizard.sheet_ids data = sheets._delete_cascade_prepare() wizard.sheet_count = data["sheet_count"] wizard.timesheet_count = data["timesheet_count"] wizard.timesheet_hours = data["timesheet_hours"] wizard.invoiced_count = data["invoiced_count"] wizard.leave_policy = data["leave_policy"] wizard.leave_count = data["leave_count"] wizard.leave_days = data["leave_days"] cancel_sheets = sheets._delete_cascade_cancel_sheets() wizard.leave_ids = cancel_sheets._sheet_leaves_to_cancel().ids wizard.partial_leave_ids = cancel_sheets._sheet_leaves_beyond_period().ids wizard.blocking_reason = "\n".join(data["blocking"]) or False wizard.summary_html = wizard._build_summary_html(data) def _build_summary_html(self, data): self.ensure_one() if not data["sheet_count"]: return Markup("

%s

") % _("No timesheet sheet was selected.") parts = [] for section in data["sections"]: parts.append(Markup("

%s

") % section["title"]) parts.append( Markup("") % Markup("").join( Markup("
  • %s
  • ") % line for line in section["lines"] ) ) return Markup("").join(parts) def action_confirm_delete(self): self.ensure_one() self.sheet_ids._with_delete_cascade().unlink() return {"type": "ir.actions.act_window_close"}