add hr_timesheet_sheet_no_review, hr_timesheet_sheet_holidays, hr_timesheet_sheet_delete_cascade
This commit is contained in:
parent
b07082f70d
commit
8b0d0bb6cc
53 changed files with 3953 additions and 0 deletions
1
hr_timesheet_sheet_no_review/wizards/__init__.py
Normal file
1
hr_timesheet_sheet_no_review/wizards/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import unfreeze_wizard
|
||||
79
hr_timesheet_sheet_no_review/wizards/unfreeze_wizard.py
Normal file
79
hr_timesheet_sheet_no_review/wizards/unfreeze_wizard.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# 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
|
||||
|
||||
|
||||
class HrTimesheetSheetUnfreezeWizard(models.TransientModel):
|
||||
_name = "hr_timesheet.sheet.unfreeze.wizard"
|
||||
_description = "Unfreeze Pending Timesheet Sheets"
|
||||
|
||||
sheet_count = fields.Integer(
|
||||
string="Frozen Sheets",
|
||||
compute="_compute_frozen_data",
|
||||
)
|
||||
timesheet_count = fields.Integer(
|
||||
string="Blocked Timesheets",
|
||||
compute="_compute_frozen_data",
|
||||
)
|
||||
timesheet_hours = fields.Float(
|
||||
string="Blocked Hours",
|
||||
compute="_compute_frozen_data",
|
||||
)
|
||||
summary_html = fields.Html(
|
||||
string="Summary",
|
||||
compute="_compute_summary_html",
|
||||
)
|
||||
|
||||
# No @api.depends: the figures come from the state of the whole database,
|
||||
# not from any field of the wizard. The wizard is created anew every time
|
||||
# the action is opened, so they are computed once, when the dialog is read.
|
||||
def _compute_frozen_data(self):
|
||||
sheet_model = self.env["hr_timesheet.sheet"]
|
||||
sheets = sheet_model.search(sheet_model._unfreeze_domain())
|
||||
groups = self.env["account.analytic.line"].read_group(
|
||||
[("sheet_id", "in", sheets.ids)], ["unit_amount"], []
|
||||
)
|
||||
timesheet_count = groups[0]["__count"] if groups else 0
|
||||
timesheet_hours = (groups[0]["unit_amount"] if groups else 0.0) or 0.0
|
||||
for wizard in self:
|
||||
wizard.sheet_count = len(sheets)
|
||||
wizard.timesheet_count = timesheet_count
|
||||
wizard.timesheet_hours = timesheet_hours
|
||||
|
||||
@api.depends("sheet_count", "timesheet_count", "timesheet_hours")
|
||||
def _compute_summary_html(self):
|
||||
for wizard in self:
|
||||
wizard.summary_html = wizard._build_summary_html()
|
||||
|
||||
def _build_summary_html(self):
|
||||
self.ensure_one()
|
||||
if not self.sheet_count:
|
||||
return Markup("<p>%s</p>") % _(
|
||||
"There is no frozen timesheet sheet. Nothing to unfreeze."
|
||||
)
|
||||
return Markup("<p>%s</p>") % _(
|
||||
"The timesheet sheets frozen by the review workflow, and the "
|
||||
"timesheet entries they keep locked, are:"
|
||||
)
|
||||
|
||||
def action_unfreeze(self):
|
||||
self.ensure_one()
|
||||
count = self.env["hr_timesheet.sheet"]._unfreeze_sheets()
|
||||
if count:
|
||||
message = _("%s timesheet sheet(s) have been set back to draft.", count)
|
||||
else:
|
||||
message = _("No frozen timesheet sheet was found. Nothing was changed.")
|
||||
return {
|
||||
"type": "ir.actions.client",
|
||||
"tag": "display_notification",
|
||||
"params": {
|
||||
"title": _("Unfreeze Pending Sheets"),
|
||||
"message": message,
|
||||
"type": "success" if count else "info",
|
||||
"sticky": False,
|
||||
"next": {"type": "ir.actions.act_window_close"},
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?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_unfreeze_wizard_form" model="ir.ui.view">
|
||||
<field name="name">hr_timesheet.sheet.unfreeze.wizard.form</field>
|
||||
<field name="model">hr_timesheet.sheet.unfreeze.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Unfreeze Pending Sheets">
|
||||
<field name="summary_html" nolabel="1" readonly="1" />
|
||||
<group attrs="{'invisible': [('sheet_count', '=', 0)]}">
|
||||
<field name="sheet_count" />
|
||||
<field name="timesheet_count" />
|
||||
<field name="timesheet_hours" widget="float_time" />
|
||||
</group>
|
||||
<div
|
||||
class="alert alert-warning"
|
||||
role="alert"
|
||||
attrs="{'invisible': [('sheet_count', '=', 0)]}"
|
||||
>
|
||||
This is a mass operation on historical data and it cannot be
|
||||
undone: the reviewer of every approved sheet is cleared. Make
|
||||
sure you have a recent backup before you continue.
|
||||
</div>
|
||||
<footer>
|
||||
<button
|
||||
name="action_unfreeze"
|
||||
string="Unfreeze"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'invisible': [('sheet_count', '=', 0)]}"
|
||||
/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record
|
||||
id="action_hr_timesheet_sheet_unfreeze_wizard"
|
||||
model="ir.actions.act_window"
|
||||
>
|
||||
<field name="name">Unfreeze Pending Sheets</field>
|
||||
<field name="res_model">hr_timesheet.sheet.unfreeze.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="hr_timesheet_sheet_unfreeze_wizard_form" />
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue