feat(fusion_clock): default clock-in/out times as 12-hour AM/PM dropdowns
People aren't good with 24h. Default Clock-In/Out are now AM/PM dropdowns (15-min grid) instead of 24h float_time inputs. Stored value stays the float-string (e.g. '9.0'), so all downstream float(get_param(...)) reads are unchanged; persisted manually with get-snap for any off-grid value. Bump 19.0.4.0.3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
{
|
||||
'name': 'Fusion Clock',
|
||||
'version': '19.0.4.0.2',
|
||||
'version': '19.0.4.0.3',
|
||||
'category': 'Human Resources/Attendances',
|
||||
'summary': 'Complete Employee T&A with Geofencing, Shifts, Penalties, Overtime, Kiosk, Dashboard & Payroll Export',
|
||||
'description': """
|
||||
|
||||
@@ -9,17 +9,21 @@ class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
# ── Work Schedule ──────────────────────────────────────────────────
|
||||
fclk_default_clock_in_time = fields.Float(
|
||||
# 12-hour AM/PM dropdowns (people aren't good with 24h). The selection VALUE
|
||||
# is the float-as-string the backend stores (e.g. '9.0', '17.5'), so all
|
||||
# downstream float(get_param(...)) reads are unchanged. Persisted manually in
|
||||
# get_values/set_values (a 15-min grid; get snaps any off-grid stored value).
|
||||
fclk_default_clock_in_time = fields.Selection(
|
||||
selection='_fclk_time_selection',
|
||||
string='Default Clock-In Time',
|
||||
config_parameter='fusion_clock.default_clock_in_time',
|
||||
default=9.0,
|
||||
help="Default scheduled clock-in time (24h format, e.g. 9.0 = 9:00 AM).",
|
||||
default='9.0',
|
||||
help="Default scheduled clock-in time, used when no shift is assigned.",
|
||||
)
|
||||
fclk_default_clock_out_time = fields.Float(
|
||||
fclk_default_clock_out_time = fields.Selection(
|
||||
selection='_fclk_time_selection',
|
||||
string='Default Clock-Out Time',
|
||||
config_parameter='fusion_clock.default_clock_out_time',
|
||||
default=17.0,
|
||||
help="Default scheduled clock-out time (24h format, e.g. 17.0 = 5:00 PM).",
|
||||
default='17.0',
|
||||
help="Default scheduled clock-out time, used when no shift is assigned.",
|
||||
)
|
||||
fclk_auto_deduct_break = fields.Boolean(
|
||||
string='Auto-Deduct Break',
|
||||
@@ -280,11 +284,40 @@ class ResConfigSettings(models.TransientModel):
|
||||
('fclk_nfc_kiosk_debug', 'fusion_clock.nfc_kiosk_debug', False),
|
||||
]
|
||||
|
||||
@api.model
|
||||
def _fclk_time_selection(self):
|
||||
"""15-minute grid of 12-hour clock times. Each option's VALUE is the
|
||||
float-as-string the backend stores (e.g. '9.0', '17.5'); the LABEL is
|
||||
the friendly 12-hour form (e.g. '9:00 AM')."""
|
||||
opts = []
|
||||
for i in range(96):
|
||||
f = i * 0.25
|
||||
h24 = int(f)
|
||||
mm = int(round((f - h24) * 60))
|
||||
ap = 'AM' if h24 < 12 else 'PM'
|
||||
h12 = h24 % 12 or 12
|
||||
opts.append((str(f), '%d:%02d %s' % (h12, mm, ap)))
|
||||
return opts
|
||||
|
||||
@staticmethod
|
||||
def _fclk_snap_time(value, default_float):
|
||||
"""Snap a stored float-ish time to the nearest 15-min grid key string."""
|
||||
try:
|
||||
f = float(value)
|
||||
except (ValueError, TypeError):
|
||||
f = default_float
|
||||
f = round(f * 4) / 4
|
||||
if f < 0 or f >= 24:
|
||||
f = default_float
|
||||
return str(f)
|
||||
|
||||
def set_values(self):
|
||||
super().set_values()
|
||||
ICP = self.env['ir.config_parameter'].sudo()
|
||||
for fname, key, _default in self._FCLK_BOOL_PARAMS:
|
||||
ICP.set_param(key, 'True' if self[fname] else 'False')
|
||||
ICP.set_param('fusion_clock.default_clock_in_time', self.fclk_default_clock_in_time or '9.0')
|
||||
ICP.set_param('fusion_clock.default_clock_out_time', self.fclk_default_clock_out_time or '17.0')
|
||||
if self.fclk_office_user_id:
|
||||
ICP.set_param('fusion_clock.office_user_id', str(self.fclk_office_user_id.id))
|
||||
else:
|
||||
@@ -323,4 +356,8 @@ class ResConfigSettings(models.TransientModel):
|
||||
res['fclk_pay_period_start'] = fields.Date.to_date(anchor_str[:10])
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
res['fclk_default_clock_in_time'] = self._fclk_snap_time(
|
||||
ICP.get_param('fusion_clock.default_clock_in_time', '9.0'), 9.0)
|
||||
res['fclk_default_clock_out_time'] = self._fclk_snap_time(
|
||||
ICP.get_param('fusion_clock.default_clock_out_time', '17.0'), 17.0)
|
||||
return res
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
<div class="content-group">
|
||||
<div class="row mt16">
|
||||
<label for="fclk_default_clock_in_time" string="Clock-In" class="col-lg-5 o_light_label"/>
|
||||
<field name="fclk_default_clock_in_time" widget="float_time"/>
|
||||
<field name="fclk_default_clock_in_time"/>
|
||||
</div>
|
||||
<div class="row mt8">
|
||||
<label for="fclk_default_clock_out_time" string="Clock-Out" class="col-lg-5 o_light_label"/>
|
||||
<field name="fclk_default_clock_out_time" widget="float_time"/>
|
||||
<field name="fclk_default_clock_out_time"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
|
||||
Reference in New Issue
Block a user