add hr_timesheet_sheet_no_review, hr_timesheet_sheet_holidays, hr_timesheet_sheet_delete_cascade

This commit is contained in:
Luis 2026-09-22 10:58:36 +02:00
parent b07082f70d
commit 8b0d0bb6cc
53 changed files with 3953 additions and 0 deletions

View file

@ -0,0 +1 @@
from . import delete_sheet_wizard

View file

@ -0,0 +1,113 @@
# 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("<p>%s</p>") % _("No timesheet sheet was selected.")
parts = []
for section in data["sections"]:
parts.append(Markup("<h4>%s</h4>") % section["title"])
parts.append(
Markup("<ul>%s</ul>")
% Markup("").join(
Markup("<li>%s</li>") % 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"}

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2026 Criptomart
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="hr_timesheet_sheet_delete_wizard_form" model="ir.ui.view">
<field name="name">hr_timesheet.sheet.delete.wizard.form</field>
<field name="model">hr_timesheet.sheet.delete.wizard</field>
<field name="arch" type="xml">
<form string="Delete Timesheet Sheets">
<field name="sheet_ids" invisible="1" />
<field name="invoiced_count" invisible="1" />
<group>
<field name="sheet_count" />
<field name="timesheet_count" />
<field name="timesheet_hours" widget="float_time" />
</group>
<field name="summary_html" nolabel="1" readonly="1" />
<div
class="alert alert-danger"
role="alert"
attrs="{'invisible': [('blocking_reason', '!=', False)]}"
>
This cannot be undone. The selected sheets and the timesheet
entries they contain will be permanently deleted.
</div>
<div
class="alert alert-warning"
role="alert"
attrs="{'invisible': [('blocking_reason', '=', False)]}"
>
<field name="blocking_reason" nolabel="1" readonly="1" />
</div>
<footer>
<button
name="action_confirm_delete"
string="Delete permanently"
type="object"
class="btn-danger"
attrs="{'invisible': ['|', ('blocking_reason', '!=', False), ('sheet_count', '=', 0)]}"
/>
<button string="Cancel" class="btn-secondary" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_hr_timesheet_sheet_delete_wizard" model="ir.actions.act_window">
<field name="name">Delete Timesheet Sheets</field>
<field name="res_model">hr_timesheet.sheet.delete.wizard</field>
<field name="view_mode">form</field>
<field name="view_id" ref="hr_timesheet_sheet_delete_wizard_form" />
<field name="target">new</field>
<field
name="binding_model_id"
ref="hr_timesheet_sheet.model_hr_timesheet_sheet"
/>
<field name="binding_view_types">list,kanban,form</field>
</record>
</odoo>