Files
Odoo-Modules/fusion_clock/wizard/clock_period_picker_wizard.py
gsinghpal 3f78f652e7 feat(fusion_clock): bi-weekly attendance filter — pay-period filters + picker
Reuse the existing Pay Period setting (Frequency + Anchor) as the single
source of truth via a shared pure helper (models/pay_period.py); fusion.clock.report
delegates to it. Add Current/Previous/Next Pay Period filters to the attendance
search view (search-method computed booleans on hr.attendance), a Bi-Weekly Period
picker wizard (pick start -> auto +2 weeks, editable; Apply opens the filtered list)
reachable from an Attendance menu item and a dashboard tile. Window follows the
configured frequency; TZ-correct via local-day boundaries. Bump 3.14.4 -> 3.15.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 11:20:06 -04:00

67 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from datetime import timedelta
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from ..models.pay_period import compute_pay_period, period_length_days, current_prev_next
from ..models.tz_utils import get_local_today, get_local_day_boundaries
class FusionClockPeriodPicker(models.TransientModel):
"""Pick a pay-period window and open the attendance list filtered to it.
Defaults to the current pay period. Changing the start auto-fills the end
to one pay period later (two weeks by default); the end stays editable so a
fully custom range can be entered too.
"""
_name = 'fusion.clock.period.picker'
_description = 'Bi-Weekly Period Picker'
date_start = fields.Date(string='Period Start', required=True,
default=lambda self: self._fclk_default_window()[0])
date_end = fields.Date(string='Period End', required=True,
default=lambda self: self._fclk_default_window()[1])
def _fclk_config(self):
ICP = self.env['ir.config_parameter'].sudo()
return (ICP.get_param('fusion_clock.pay_period_type', 'biweekly'),
ICP.get_param('fusion_clock.pay_period_start', ''))
def _fclk_default_window(self):
frequency, anchor = self._fclk_config()
return current_prev_next(frequency, anchor, get_local_today(self.env))['current']
@api.onchange('date_start')
def _onchange_date_start(self):
if not self.date_start:
return
frequency, anchor = self._fclk_config()
length = period_length_days(frequency)
if length:
self.date_end = self.date_start + timedelta(days=length - 1)
else:
self.date_end = compute_pay_period(frequency, anchor, self.date_start)[1]
@api.constrains('date_start', 'date_end')
def _check_dates(self):
for rec in self:
if rec.date_start and rec.date_end and rec.date_end < rec.date_start:
raise ValidationError(_("Period end cannot be before period start."))
def action_apply(self):
self.ensure_one()
start_utc, _dummy = get_local_day_boundaries(self.env, self.date_start)
_dummy2, end_excl_utc = get_local_day_boundaries(self.env, self.date_end)
return {
'type': 'ir.actions.act_window',
'name': _("Attendances · %s %s") % (self.date_start, self.date_end),
'res_model': 'hr.attendance',
'view_mode': 'list,form',
'domain': ['&',
('check_in', '>=', fields.Datetime.to_string(start_utc)),
('check_in', '<', fields.Datetime.to_string(end_excl_utc))],
'target': 'current',
}