This commit is contained in:
gsinghpal
2026-02-23 00:32:20 -05:00
parent d6bac8e623
commit e8e554de95
549 changed files with 1330 additions and 124935 deletions

View File

@@ -7,7 +7,12 @@
<field name="model">fusion.clock.location</field>
<field name="arch" type="xml">
<form string="Clock Location">
<header/>
<header>
<button name="action_geocode_address" type="object"
string="Geocode Address" class="btn-primary"
icon="fa-map-marker"
confirm="This will update latitude/longitude from the address using Google Maps API."/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_view_attendances" type="object"
@@ -24,8 +29,7 @@
</div>
<group>
<group string="Address">
<field name="address" widget="fclk_places_address"
placeholder="Start typing an address or place name..."/>
<field name="address" placeholder="123 Business Ave, San Francisco, CA"/>
<field name="timezone"/>
</group>
<group string="Geofence">
@@ -48,9 +52,9 @@
</group>
</group>
<!-- Interactive Map (drag pin to adjust, search places) -->
<group string="Map">
<widget name="fclk_map" colspan="2"/>
<!-- Google Maps Static Preview -->
<group string="Map Preview" invisible="not latitude or not longitude">
<field name="map_url" widget="image_url" string="Map" invisible="not map_url"/>
</group>
<group string="Notes">

View File

@@ -14,20 +14,6 @@
parent="menu_fusion_clock_root"
sequence="10"/>
<menuitem id="menu_fusion_clock_employee_overview"
name="Employee Overview"
parent="menu_fusion_clock_attendance"
action="action_fusion_clock_employee_overview"
sequence="5"
groups="group_fusion_clock_manager"/>
<menuitem id="menu_fusion_clock_by_pay_period"
name="By Pay Period"
parent="menu_fusion_clock_attendance"
action="action_fusion_clock_attendance_by_period"
sequence="8"
groups="group_fusion_clock_manager"/>
<menuitem id="menu_fusion_clock_attendance_list"
name="All Attendances"
parent="menu_fusion_clock_attendance"
@@ -66,18 +52,10 @@
sequence="90"
groups="group_fusion_clock_manager"/>
<record id="action_fusion_clock_config_settings" model="ir.actions.act_window">
<field name="name">Fusion Clock Settings</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">current</field>
<field name="context">{'module': 'fusion_clock'}</field>
</record>
<menuitem id="menu_fusion_clock_settings"
name="Settings"
parent="menu_fusion_clock_config"
action="action_fusion_clock_config_settings"
action="base.res_config_setting_act_window"
sequence="10"
groups="group_fusion_clock_manager"/>

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- ================================================================
Extend Attendance List View - add Fusion Clock columns
================================================================ -->
<!-- Extend Attendance List View -->
<record id="view_hr_attendance_list_fusion_clock" model="ir.ui.view">
<field name="name">hr.attendance.list.fusion.clock</field>
<field name="model">hr.attendance</field>
@@ -12,100 +10,14 @@
<xpath expr="//field[@name='worked_hours']" position="after">
<field name="x_fclk_net_hours" string="Net Hours" widget="float_time" optional="show"/>
<field name="x_fclk_break_minutes" string="Break (min)" optional="show"/>
<field name="x_fclk_location_id" string="In Location" optional="show"/>
<field name="x_fclk_out_location_id" string="Out Location" optional="hide"/>
<field name="x_fclk_pay_period" string="Pay Period" optional="hide"/>
<field name="x_fclk_location_id" string="Location" optional="show"/>
<field name="x_fclk_clock_source" string="Source" optional="hide"/>
<field name="x_fclk_auto_clocked_out" string="Auto Out" optional="hide"/>
</xpath>
</field>
</record>
<!-- ================================================================
Dedicated list view for pay-period views
Shows the columns needed for attendance detail
================================================================ -->
<record id="view_hr_attendance_list_by_period" model="ir.ui.view">
<field name="name">hr.attendance.list.by.period</field>
<field name="model">hr.attendance</field>
<field name="arch" type="xml">
<list default_order="check_in desc">
<field name="employee_id" optional="show"/>
<field name="check_in" string="Clock In"/>
<field name="check_out" string="Clock Out"/>
<field name="x_fclk_location_id" string="In Location" optional="show"/>
<field name="x_fclk_out_location_id" string="Out Location" optional="show"/>
<field name="worked_hours" string="Total Hours" widget="float_time"/>
<field name="x_fclk_break_minutes" string="Break (min)"/>
<field name="x_fclk_net_hours" string="Net Hours" widget="float_time"/>
<field name="overtime_hours" string="Extra Hours" widget="float_time" optional="show"/>
<field name="x_fclk_pay_period" string="Pay Period" optional="show"/>
<field name="x_fclk_clock_source" string="Source" optional="hide"/>
</list>
</field>
</record>
<!-- ================================================================
Dedicated search view for pay-period actions
Group-by filters in correct order: Pay Period first, Employee second
================================================================ -->
<record id="view_hr_attendance_search_by_period" model="ir.ui.view">
<field name="name">hr.attendance.search.by.period</field>
<field name="model">hr.attendance</field>
<field name="arch" type="xml">
<search string="Search Attendance">
<field name="employee_id"/>
<field name="department_id" operator="child_of"/>
<field name="x_fclk_location_id" string="Location"/>
<field name="x_fclk_pay_period" string="Pay Period"/>
<separator/>
<filter string="My Attendances" name="myattendances"
domain="[('employee_id.user_id', '=', uid)]"/>
<filter string="At Work" name="nocheckout"
domain="[('check_out', '=', False)]"/>
<separator/>
<filter string="Date" name="check_in_filter" date="check_in"/>
<separator/>
<filter string="Pay Period" name="group_pay_period"
context="{'group_by': 'x_fclk_pay_period'}"/>
<filter string="Employee" name="group_employee"
context="{'group_by': 'employee_id'}"/>
<filter string="Month" name="group_month"
context="{'group_by': 'check_in:month'}"/>
<filter string="Location" name="group_location"
context="{'group_by': 'x_fclk_location_id'}"/>
</search>
</field>
</record>
<!-- ================================================================
Extend base Attendance Search View - add our extra filters
================================================================ -->
<record id="view_hr_attendance_search_fusion_clock" model="ir.ui.view">
<field name="name">hr.attendance.search.fusion.clock</field>
<field name="model">hr.attendance</field>
<field name="inherit_id" ref="hr_attendance.hr_attendance_view_filter"/>
<field name="arch" type="xml">
<xpath expr="//search" position="inside">
<field name="x_fclk_location_id"/>
<field name="x_fclk_pay_period" string="Pay Period"/>
<separator/>
<filter name="fclk_portal" string="Portal" domain="[('x_fclk_clock_source', '=', 'portal')]"/>
<filter name="fclk_systray" string="Systray" domain="[('x_fclk_clock_source', '=', 'systray')]"/>
<filter name="fclk_auto" string="Auto Clock-Out" domain="[('x_fclk_auto_clocked_out', '=', True)]"/>
<separator/>
<filter name="fclk_has_penalty" string="Has Penalty" domain="[('x_fclk_penalty_ids', '!=', False)]"/>
<separator/>
<filter name="group_pay_period" string="Pay Period" context="{'group_by': 'x_fclk_pay_period'}"/>
<filter name="group_location" string="Location" context="{'group_by': 'x_fclk_location_id'}"/>
<filter name="group_source" string="Source" context="{'group_by': 'x_fclk_clock_source'}"/>
</xpath>
</field>
</record>
<!-- ================================================================
Extend Attendance Form View - add Fusion Clock details
================================================================ -->
<!-- Extend Attendance Form View -->
<record id="view_hr_attendance_form_fusion_clock" model="ir.ui.view">
<field name="name">hr.attendance.form.fusion.clock</field>
<field name="model">hr.attendance</field>
@@ -115,11 +27,9 @@
<group string="Fusion Clock Details" name="fusion_clock_details">
<group>
<field name="x_fclk_location_id"/>
<field name="x_fclk_out_location_id"/>
<field name="x_fclk_clock_source"/>
<field name="x_fclk_break_minutes"/>
<field name="x_fclk_net_hours" widget="float_time"/>
<field name="x_fclk_pay_period"/>
</group>
<group>
<field name="x_fclk_in_distance"/>
@@ -143,127 +53,25 @@
</field>
</record>
<!-- ================================================================
Employee Kanban View - card per employee showing clock stats
================================================================ -->
<record id="view_hr_employee_kanban_fusion_clock" model="ir.ui.view">
<field name="name">hr.employee.kanban.fusion.clock</field>
<field name="model">hr.employee</field>
<!-- Extend Attendance Search View -->
<record id="view_hr_attendance_search_fusion_clock" model="ir.ui.view">
<field name="name">hr.attendance.search.fusion.clock</field>
<field name="model">hr.attendance</field>
<field name="inherit_id" ref="hr_attendance.hr_attendance_view_filter"/>
<field name="arch" type="xml">
<kanban class="o_hr_employee_kanban" sample="1">
<field name="id"/>
<field name="name"/>
<field name="job_title"/>
<field name="department_id"/>
<field name="attendance_state"/>
<field name="x_fclk_period_hours"/>
<field name="x_fclk_period_label"/>
<field name="avatar_128"/>
<templates>
<t t-name="card">
<div class="d-flex flex-column h-100">
<div class="d-flex align-items-center gap-3 mb-3">
<field name="avatar_128" widget="image"
options="{'size': [48, 48]}"
class="rounded-circle flex-shrink-0"/>
<div class="flex-grow-1 min-w-0">
<div class="d-flex align-items-center gap-2">
<field name="name" class="fw-bold text-truncate"/>
<span t-if="record.attendance_state.raw_value == 'checked_in'"
class="badge rounded-pill text-bg-success flex-shrink-0">IN</span>
<span t-if="record.attendance_state.raw_value == 'checked_out'"
class="badge rounded-pill text-bg-secondary flex-shrink-0">OUT</span>
</div>
<div class="text-muted small text-truncate">
<field name="job_title"/>
</div>
</div>
</div>
<div class="mb-2 px-1">
<div class="d-flex justify-content-between align-items-baseline">
<span class="text-muted small">Period Hours</span>
<span class="fw-bold">
<field name="x_fclk_period_hours" widget="float_time"/>
</span>
</div>
<div class="text-muted mt-1" style="font-size: 0.75rem;">
<field name="x_fclk_period_label"/>
</div>
</div>
<div class="flex-grow-1"/>
<button name="action_fclk_open_attendance" type="object"
class="btn btn-sm btn-outline-primary w-100 mt-2">
<i class="fa fa-list-ul me-1"/>View Attendance
</button>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- ================================================================
Employee Kanban Search View
================================================================ -->
<record id="view_hr_employee_search_fusion_clock" model="ir.ui.view">
<field name="name">hr.employee.search.fusion.clock</field>
<field name="model">hr.employee</field>
<field name="arch" type="xml">
<search string="Search Employees">
<field name="name"/>
<field name="department_id"/>
<field name="job_title"/>
<xpath expr="//search" position="inside">
<field name="x_fclk_location_id"/>
<separator/>
<filter name="group_department" string="Department"
context="{'group_by': 'department_id'}"/>
</search>
<filter name="fclk_portal" string="Portal" domain="[('x_fclk_clock_source', '=', 'portal')]"/>
<filter name="fclk_systray" string="Systray" domain="[('x_fclk_clock_source', '=', 'systray')]"/>
<filter name="fclk_auto" string="Auto Clock-Out" domain="[('x_fclk_auto_clocked_out', '=', True)]"/>
<separator/>
<filter name="fclk_has_penalty" string="Has Penalty" domain="[('x_fclk_penalty_ids', '!=', False)]"/>
<separator/>
<filter name="group_location" string="Location" context="{'group_by': 'x_fclk_location_id'}"/>
<filter name="group_source" string="Source" context="{'group_by': 'x_fclk_clock_source'}"/>
</xpath>
</field>
</record>
<!-- ================================================================
Action: Employee Overview (Kanban cards)
================================================================ -->
<record id="action_fusion_clock_employee_overview" model="ir.actions.act_window">
<field name="name">Employee Overview</field>
<field name="res_model">hr.employee</field>
<field name="view_mode">kanban</field>
<field name="domain">[('x_fclk_enable_clock', '=', True)]</field>
<field name="search_view_id" ref="view_hr_employee_search_fusion_clock"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">No clock-enabled employees found.</p>
<p>Enable Fusion Clock on employee records to see them here.</p>
</field>
</record>
<record id="action_fusion_clock_employee_overview_kanban" model="ir.actions.act_window.view">
<field name="sequence">1</field>
<field name="view_mode">kanban</field>
<field name="view_id" ref="view_hr_employee_kanban_fusion_clock"/>
<field name="act_window_id" ref="action_fusion_clock_employee_overview"/>
</record>
<!-- ================================================================
Action: Attendance By Pay Period (list grouped by period then employee)
================================================================ -->
<record id="action_fusion_clock_attendance_by_period" model="ir.actions.act_window">
<field name="name">Attendance by Pay Period</field>
<field name="res_model">hr.attendance</field>
<field name="view_mode">list,form</field>
<field name="search_view_id" ref="view_hr_attendance_search_by_period"/>
<field name="context">{
'search_default_group_pay_period': 1,
'search_default_group_employee': 1,
}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">No attendance records found.</p>
</field>
</record>
<record id="action_fusion_clock_attendance_by_period_list" model="ir.actions.act_window.view">
<field name="sequence">1</field>
<field name="view_mode">list</field>
<field name="view_id" ref="view_hr_attendance_list_by_period"/>
<field name="act_window_id" ref="action_fusion_clock_attendance_by_period"/>
</record>
</odoo>

View File

@@ -1,27 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Add Clock In/Out tile to the Fusion portal home grid -->
<!-- Add Clock link to portal home -->
<template id="portal_my_home_clock" name="Portal My Home: Clock"
inherit_id="fusion_authorizer_portal.portal_my_home_authorizer" priority="60">
<xpath expr="//div[hasclass('row')][hasclass('g-3')][hasclass('mb-4')]" position="inside">
<t t-set="pfab_emp_home" t-value="request.env['hr.employee'].sudo().search([('user_id','=',request.env.uid)], limit=1)"/>
<t t-if="pfab_emp_home and pfab_emp_home.x_fclk_enable_clock">
<div class="col-md-6">
<a href="/my/clock" class="card h-100 border-0 shadow-sm text-decoration-none" style="border-radius: 12px; min-height: 100px;">
<div class="card-body d-flex align-items-center p-4">
<div class="me-3">
<div class="rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px; background: linear-gradient(135deg, #0d9488 0%, #2563eb 100%);">
<i class="fa fa-clock-o fa-lg text-white"/>
</div>
</div>
<div>
<h5 class="mb-1 text-dark">Clock In / Out</h5>
<small class="text-muted">Punch in, view timesheets, and reports</small>
</div>
</div>
</a>
</div>
inherit_id="portal.portal_my_home" priority="60">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
<t t-call="portal.portal_docs_entry">
<t t-set="icon" t-value="'/fusion_clock/static/description/icon.png'"/>
<t t-set="title">Clock In / Out</t>
<t t-set="url" t-value="'/my/clock'"/>
<t t-set="text">Punch in, view timesheets, and download attendance reports</t>
<t t-set="placeholder_count" t-value="'clock_count'"/>
</t>
</xpath>
</template>
@@ -33,8 +22,8 @@
<template id="portal_layout_clock_fab" name="Portal Clock FAB"
inherit_id="portal.portal_layout">
<xpath expr="//div[@id='wrap']" position="after">
<t t-set="pfab_emp" t-value="fclk_employee if fclk_employee is defined else False"/>
<t t-if="pfab_emp and pfab_emp.x_fclk_enable_clock">
<t t-set="__fclk_emp" t-value="fclk_employee if fclk_employee is defined else False"/>
<t t-if="__fclk_emp and __fclk_emp.x_fclk_enable_clock">
<div id="fclk-portal-fab"
t-att-data-checked-in="'true' if fclk_checked_in else 'false'"
t-att-data-check-in-time="fclk_check_in_time or ''"
@@ -164,7 +153,7 @@
<t t-if="is_checked_in">Time Elapsed</t>
<t t-else="">Ready to Clock In</t>
</div>
<div class="fclk-timer" id="fclk-timer">00:00:00</div>
<div class="fclk-timer" id="fclk-timer">00 : 00 : 00</div>
</div>
<!-- Clock Button -->
@@ -173,13 +162,13 @@
t-attf-class="fclk-clock-btn {{ 'fclk-clock-btn-out' if is_checked_in else '' }}">
<div class="fclk-btn-ripple"></div>
<svg id="fclk-btn-icon-play" class="fclk-btn-icon"
t-attf-style="display: {{ 'none' if is_checked_in else 'block' }}; margin-left: 4px;"
width="40" height="40" viewBox="0 0 24 24" fill="white">
<polygon points="6 3 20 12 6 21 6 3"/>
t-attf-style="display: {{ 'none' if is_checked_in else 'block' }}"
width="48" height="48" viewBox="0 0 24 24" fill="white">
<polygon points="5 3 19 12 5 21 5 3"/>
</svg>
<svg id="fclk-btn-icon-stop" class="fclk-btn-icon"
t-attf-style="display: {{ 'block' if is_checked_in else 'none' }}"
width="36" height="36" viewBox="0 0 24 24" fill="white">
width="40" height="40" viewBox="0 0 24 24" fill="white">
<rect x="4" y="4" width="16" height="16" rx="2"/>
</svg>
</button>

View File

@@ -12,148 +12,137 @@
<!-- Work Schedule -->
<block title="Work Schedule" name="fclk_work_schedule">
<setting string="Default Clock-In Time" help="Scheduled start of shift. Used for penalty and auto clock-out calculations.">
<span class="me-2">Clock-In</span>
<field name="fclk_default_clock_in_time" widget="float_time"
class="text-center" style="width: 6ch;"/>
<span class="ms-2 text-muted">e.g. 09:00 = 9 AM</span>
<setting string="Default Clock-In Time" help="The scheduled start time for employees.">
<div class="content-group">
<div class="row mt16">
<label for="fclk_default_clock_in_time" class="col-lg-3"/>
<field name="fclk_default_clock_in_time" widget="float_time"/>
</div>
</div>
</setting>
<setting string="Default Clock-Out Time" help="Scheduled end of shift. Used for penalty and auto clock-out calculations.">
<span class="me-2">Clock-Out</span>
<field name="fclk_default_clock_out_time" widget="float_time"
class="text-center" style="width: 6ch;"/>
<span class="ms-2 text-muted">e.g. 17:00 = 5 PM</span>
<setting string="Default Clock-Out Time" help="The scheduled end time for employees.">
<div class="content-group">
<div class="row mt16">
<label for="fclk_default_clock_out_time" class="col-lg-3"/>
<field name="fclk_default_clock_out_time" widget="float_time"/>
</div>
</div>
</setting>
</block>
<!-- Break Settings -->
<block title="Break Settings" name="fclk_break_settings">
<setting string="Auto-Deduct Break" help="Automatically deduct unpaid break from total worked hours. Applies to portal/FAB clock-outs AND manually entered attendance.">
<setting string="Auto-Deduct Break" help="Automatically deduct unpaid break from worked hours.">
<field name="fclk_auto_deduct_break"/>
<div invisible="not fclk_auto_deduct_break" class="mt8">
<span class="me-2">Break Duration</span>
<field name="fclk_default_break_minutes" class="text-center" style="width: 6ch;"/>
<span class="ms-2">minutes</span>
<span class="ms-3 text-muted">e.g. 30 = half-hour unpaid break</span>
<br/>
<span class="me-2 mt8 d-inline-block">Threshold</span>
<field name="fclk_break_threshold_hours" widget="float_time"
class="text-center" style="width: 6ch;"/>
<span class="ms-2">hours</span>
<span class="ms-3 text-muted">break deducted only if shift exceeds this</span>
<br/>
<button name="action_backfill_breaks" type="object"
string="Apply Break to Past Records"
class="btn btn-secondary mt8" icon="fa-clock-o"
confirm="This will apply break deduction to all past attendance records that are missing it. Continue?"/>
<span class="ms-2 text-muted mt8 d-inline-block">
Applies break to historical records that were entered manually or before break was enabled
</span>
<div class="content-group" invisible="not fclk_auto_deduct_break">
<div class="row mt16">
<label for="fclk_default_break_minutes" class="col-lg-3"/>
<field name="fclk_default_break_minutes"/>
<span class="ms-1">minutes</span>
</div>
<div class="row mt8">
<label for="fclk_break_threshold_hours" class="col-lg-3"/>
<field name="fclk_break_threshold_hours" widget="float_time"/>
<span class="ms-1">(only deduct if shift exceeds this)</span>
</div>
</div>
</setting>
</block>
<!-- Auto Clock-Out & Grace Period -->
<block title="Auto Clock-Out" name="fclk_auto_clockout">
<setting string="Enable Auto Clock-Out" help="Automatically clock out employees who forget to clock out.">
<setting string="Enable Auto Clock-Out" help="Automatically clock out employees after shift + grace period.">
<field name="fclk_enable_auto_clockout"/>
<div invisible="not fclk_enable_auto_clockout" class="mt8">
<span class="me-2">Grace Period</span>
<field name="fclk_grace_period_minutes" class="text-center" style="width: 6ch;"/>
<span class="ms-2">minutes after scheduled end</span>
<br/>
<span class="me-2 mt8 d-inline-block">Max Shift</span>
<field name="fclk_max_shift_hours" widget="float_time"
class="text-center" style="width: 6ch;"/>
<span class="ms-2">hours</span>
<span class="ms-3 text-muted">safety net: force clock-out after this</span>
<div class="content-group" invisible="not fclk_enable_auto_clockout">
<div class="row mt16">
<label for="fclk_grace_period_minutes" class="col-lg-3"/>
<field name="fclk_grace_period_minutes"/>
<span class="ms-1">minutes grace after scheduled end</span>
</div>
<div class="row mt8">
<label for="fclk_max_shift_hours" class="col-lg-3"/>
<field name="fclk_max_shift_hours" widget="float_time"/>
<span class="ms-1">max shift safety net</span>
</div>
</div>
</setting>
</block>
<!-- Penalties -->
<block title="Penalty Tracking" name="fclk_penalties">
<setting string="Enable Penalties" help="Track late clock-ins and early clock-outs for each employee.">
<setting string="Enable Penalties" help="Track late clock-in and early clock-out.">
<field name="fclk_enable_penalties"/>
<div invisible="not fclk_enable_penalties" class="mt8">
<span class="me-2">Grace</span>
<field name="fclk_penalty_grace_minutes" class="text-center" style="width: 6ch;"/>
<span class="ms-2">minutes before a penalty is logged</span>
<div class="content-group" invisible="not fclk_enable_penalties">
<div class="row mt16">
<label for="fclk_penalty_grace_minutes" class="col-lg-3"/>
<field name="fclk_penalty_grace_minutes"/>
<span class="ms-1">minutes grace before penalty</span>
</div>
</div>
</setting>
</block>
<!-- Pay Period -->
<block title="Pay Period" name="fclk_pay_period">
<setting string="Pay Period Schedule" help="Defines how pay periods are calculated. Weekly and Bi-Weekly require an anchor date below. Semi-Monthly uses 1st-15th and 16th-end. Monthly uses 1st-end.">
<div class="mt8">
<span class="me-2">Schedule</span>
<field name="fclk_pay_period_type" class="d-inline-block"/>
</div>
</setting>
<setting string="Anchor Date" help="The first day of any actual pay period. All periods are calculated forward and backward from this date in weekly or biweekly increments. Not used for Semi-Monthly or Monthly.">
<div class="mt8">
<field name="fclk_pay_period_start" class="d-inline-block"
placeholder="Pick the start of a real pay period"/>
<span class="ms-3 text-muted">
Pick the first day of any real pay period
</span>
</div>
</setting>
<setting string="Current Period Preview" help="Shows the current pay period based on today and the settings above. Use this to verify your anchor date is correct.">
<div class="mt8">
<field name="fclk_pay_period_preview" class="fw-bold text-primary"/>
<setting string="Pay Period Schedule" help="Defines how often reports are generated.">
<div class="content-group">
<div class="row mt16">
<label for="fclk_pay_period_type" class="col-lg-3"/>
<field name="fclk_pay_period_type"/>
</div>
<div class="row mt8">
<label for="fclk_pay_period_start" class="col-lg-3"/>
<field name="fclk_pay_period_start"/>
</div>
</div>
</setting>
</block>
<!-- Reports -->
<block title="Reports &amp; Email" name="fclk_reports">
<setting string="Auto-Generate Reports" help="Automatically generate a summary report at the end of each pay period.">
<setting string="Auto-Generate Reports" help="Automatically generate reports at the end of each pay period.">
<field name="fclk_auto_generate_reports"/>
</setting>
<setting string="Send Employee Copies" help="Email each employee a copy of their individual timesheet at the end of every pay period.">
<setting string="Send Employee Copies" help="Email individual reports to each employee.">
<field name="fclk_send_employee_reports"/>
</setting>
<setting string="Manager Report Recipients" help="Comma-separated email addresses. A batch summary of all employees will be sent to these addresses at the end of every pay period.">
<div class="mt8">
<field name="fclk_report_recipient_emails" class="o_input w-100"
placeholder="manager@company.com, hr@company.com"/>
</div>
</setting>
<setting string="Generate Historical Reports" help="Create reports for all past pay periods that have attendance data but no report yet. No emails will be sent for these. Use this after first install or when changing pay period settings.">
<div class="mt8">
<button name="action_backfill_reports" type="object"
string="Generate Historical Reports"
class="btn btn-secondary" icon="fa-history"
confirm="This will create reports for all past pay periods. No emails will be sent. This may take a few minutes depending on the amount of data. Continue?"/>
<setting string="Manager Report Recipients" help="Comma-separated emails for batch report delivery.">
<div class="content-group">
<div class="row mt16">
<label for="fclk_report_recipient_emails" class="col-lg-3"/>
<field name="fclk_report_recipient_emails" class="o_input" placeholder="manager@company.com, hr@company.com"/>
</div>
</div>
</setting>
</block>
<!-- Clock Locations -->
<block title="Clock Locations" name="fclk_locations">
<setting string="Manage Locations" help="Configure geofenced clock-in/out locations with GPS coordinates and allowed radius.">
<div class="mt8">
<button name="%(fusion_clock.action_fusion_clock_location)d" type="action"
string="Manage Locations" class="btn btn-primary" icon="fa-map-marker"/>
<setting string="Manage Locations" help="Configure geofenced clock-in/out locations with GPS coordinates and radius.">
<div class="content-group">
<div class="mt16">
<button name="%(fusion_clock.action_fusion_clock_location)d" type="action"
string="Manage Locations" class="btn btn-primary" icon="fa-map-marker"/>
</div>
</div>
</setting>
</block>
<!-- Google Maps -->
<block title="Google Maps" name="fclk_google_maps">
<setting string="Google Maps API Key" help="Required for geocoding addresses and showing map previews on clock locations.">
<div class="mt8">
<field name="fclk_google_maps_api_key" class="o_input w-100"
placeholder="AIza..." password="True"/>
<setting string="Google Maps API Key" help="Required for location geocoding and map previews.">
<div class="content-group">
<div class="row mt16">
<label for="fclk_google_maps_api_key" class="col-lg-3"/>
<field name="fclk_google_maps_api_key" class="o_input" placeholder="AIza..." password="True"/>
</div>
</div>
</setting>
</block>
<!-- Sounds -->
<block title="Sounds" name="fclk_sounds">
<setting string="Clock Sounds" help="Play an audio chime on clock-in and a different one on clock-out.">
<setting string="Clock Sounds" help="Play audio feedback on clock-in and clock-out.">
<field name="fclk_enable_sounds"/>
</setting>
</block>