addons-cm/hr_timesheet_sheet_no_review/models/hr_timesheet_sheet.py

59 lines
2.1 KiB
Python

# Copyright 2026 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging
from odoo import api, models
from odoo.osv import expression
_logger = logging.getLogger(__name__)
class HrTimesheetSheet(models.Model):
_inherit = "hr_timesheet.sheet"
@api.model
def _unfreeze_domain(self):
"""Hook for extensions: which sheets are considered frozen."""
return [("state", "in", ("confirm", "done"))]
@api.model
def _unfreeze_sheets(self, sheets=None):
"""Send frozen sheets back to draft. Returns the number of sheets affected.
Without ``sheets``, every frozen sheet the current user can see is
released, which is the historical behaviour of this hook. With
``sheets``, only those of them that are still frozen are released: the
wizard passes the recordset it showed the user, so the confirmation
message counts what the warning announced and not what the database
happens to hold by the time the button is pressed.
The update is issued in SQL on purpose: going through ``write()`` would
trigger the sheet recomputation and one tracking message per sheet, on a
volume that is measured in thousands of records.
"""
domain = self._unfreeze_domain()
if sheets is not None:
domain = expression.AND([domain, [("id", "in", sheets.ids)]])
sheets = self.search(domain)
if not sheets:
_logger.info("No frozen timesheet sheets to unfreeze.")
return 0
sheets.check_access_rights("write")
sheets.check_access_rule("write")
self.env.flush_all()
self.env.cr.execute(
"""
UPDATE hr_timesheet_sheet
SET state = 'draft',
reviewer_id = NULL,
write_uid = %s,
write_date = (now() at time zone 'UTC')
WHERE id IN %s
""",
(self.env.uid, tuple(sheets.ids)),
)
count = self.env.cr.rowcount
self.env.invalidate_all(flush=False)
_logger.info("Unfroze %s timesheet sheet(s).", count)
return count