Steps: - As admin, go to Settings > Users & Companies > Users - Edit Mark Demo (demo) - In Human Resources > Attendances, select Manual Attendance or blank - As demo, go to My Profile - Click the smart button showing the hours worked for the last month - Remove all filters Bug: The demo user, who hasn't the rights to see the other employees attendances, can see them. Explanation: Every user must have the right to read attendances in order to see their own attendances. Not giving the users the read rights in the security record rule prevents the record rule from being applied when reading attendances. This makes the read access rights the only rule and allows everyone to see the attendances of the others. This commit also fixes the default selected employee when going to the attendances tree view on these paths: - User - Employee - User > Employee In fact, sometime, `active_id` is the ÌD of the user and not of the employee. This leads to incorrect results since another employee's attendances are shown. Finally, this commit prevents users from creating attendances from other apps since only attendance officers and above can have access to the creation form within the Attendances app. opw:2440117 closes odoo/odoo#65334 X-original-commit: b3247c81200200590d669b76a58d06e6adf66d69 Signed-off-by: backspac <backspac@users.noreply.github.com>
173 lines
10 KiB
XML
173 lines
10 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<odoo>
|
|
<record id="view_employee_form_inherit_hr_attendance" model="ir.ui.view">
|
|
<field name="name">hr.employee</field>
|
|
<field name="model">hr.employee</field>
|
|
<field name="inherit_id" ref="hr.view_employee_form"/>
|
|
<field name="priority">20</field>
|
|
<field name="groups_id" eval="[(4,ref('hr_attendance.group_hr_attendance_user'))]"/>
|
|
<field name="arch" type="xml">
|
|
<xpath expr="//button[@id='hr_presence_button']" position="attributes">
|
|
<attribute name="attrs">
|
|
{'invisible': ['|', '|', ('user_id', '=', False), ('hr_presence_state', '=', 'absent'), ('attendance_state', '=', 'checked_in')]}
|
|
</attribute>
|
|
</xpath>
|
|
<xpath expr="//div[@name='button_box']" position="inside">
|
|
<field name="attendance_state" invisible="1"/>
|
|
<button name="%(hr_attendance_action_employee)d"
|
|
id="hr_attendance_button"
|
|
class="oe_stat_button"
|
|
type="action" attrs="{'invisible': [
|
|
'|', ('attendance_state', '=', False),
|
|
'&',
|
|
('hr_presence_state', '=', 'present'),
|
|
('attendance_state', '=', 'checked_out')]}"
|
|
context="{'search_default_employee_id': id}">
|
|
<div role="img" id="oe_hr_attendance_status" class="fa fa-fw fa-circle o_button_icon oe_hr_attendance_status_green" attrs="{'invisible': [('attendance_state', '=', 'checked_out')]}" aria-label="Available" title="Available"/>
|
|
<div role="img" id="oe_hr_attendance_status" class="fa fa-fw fa-circle o_button_icon oe_hr_attendance_status_red" attrs="{'invisible': [('attendance_state', '=', 'checked_in')]}" aria-label="Not available" title="Not available"/>
|
|
<div class="o_stat_info" attrs="{'invisible': ['|', ('last_check_in', '=', False), ('last_check_out', '!=', False)]}">
|
|
<span class="o_stat_text">Attended Since</span>
|
|
<span class="o_stat_value"><field name="last_check_in" widget="relative_time"/></span>
|
|
</div>
|
|
<div class="o_stat_info" attrs="{'invisible': [('last_check_out', '=', False)]}">
|
|
<span class="o_stat_text">Not Attended Since</span>
|
|
<span class="o_stat_value"><field name="last_check_out" widget="relative_time"/></span>
|
|
</div>
|
|
<div class="o_stat_info" attrs="{'invisible': [('last_check_in', '!=', False)]}">
|
|
<span class="o_stat_text">Attendance</span>
|
|
</div>
|
|
</button>
|
|
<button name="%(hr_attendance_action)d"
|
|
class="oe_stat_button"
|
|
icon="fa-clock-o"
|
|
type="action"
|
|
context="{'search_default_employee_id': id, 'search_default_check_in_filter': '1'}"
|
|
groups="base.group_user"
|
|
help="Worked hours last month">
|
|
<div class="o_field_widget o_stat_info">
|
|
<span class="o_stat_value">
|
|
<field name="hours_last_month_display"/> Hours
|
|
</span>
|
|
<span class="o_stat_text">
|
|
Last Month
|
|
</span>
|
|
</div>
|
|
</button>
|
|
</xpath>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="hr_user_view_form" model="ir.ui.view">
|
|
<field name="name">hr.user.preferences.view.form.attendance.inherit</field>
|
|
<field name="model">res.users</field>
|
|
<field name="inherit_id" ref="hr.res_users_view_form_profile"/>
|
|
<field name="arch" type="xml">
|
|
<xpath expr="//button[@id='hr_presence_button']" position="attributes">
|
|
<attribute name="attrs">
|
|
{'invisible': ['|', ('hr_presence_state', '=', 'absent'), ('attendance_state', '=', 'checked_in')]}
|
|
</attribute>
|
|
</xpath>
|
|
<xpath expr="//div[@name='button_box']" position="inside">
|
|
<field name="attendance_state" invisible="1"/>
|
|
<button name="%(hr_attendance_action_my_attendances)d"
|
|
id="hr_attendance_button"
|
|
class="oe_stat_button"
|
|
invisible="context.get('from_my_profile', False)"
|
|
type="action" attrs="{'invisible': ['|', ('attendance_state', '=', False), '&', ('hr_presence_state', '=', 'present'), ('attendance_state', '=', 'checked_out')]}">
|
|
<div role="img" id="oe_hr_attendance_status" class="fa fa-fw fa-circle o_button_icon oe_hr_attendance_status_green" attrs="{'invisible': [('attendance_state', '=', 'checked_out')]}" aria-label="Available" title="Available"/>
|
|
<div role="img" id="oe_hr_attendance_status" class="fa fa-fw fa-circle o_button_icon oe_hr_attendance_status_red" attrs="{'invisible': [('attendance_state', '=', 'checked_in')]}" aria-label="Not available" title="Not available"/>
|
|
<div class="o_stat_info" attrs="{'invisible': ['|', ('last_check_in', '=', False), ('last_check_out', '!=', False)]}">
|
|
<span class="o_stat_text">Attended Since</span>
|
|
<span class="o_stat_value"><field name="last_check_in" widget="relative_time"/></span>
|
|
</div>
|
|
<div class="o_stat_info" attrs="{'invisible': [('last_check_out', '=', False)]}">
|
|
<span class="o_stat_text">Not Attended Since</span>
|
|
<span class="o_stat_value"><field name="last_check_out" widget="relative_time"/></span>
|
|
</div>
|
|
<div class="o_stat_info" attrs="{'invisible': [('last_check_in', '!=', False)]}">
|
|
<span class="o_stat_text">Attendance</span>
|
|
</div>
|
|
</button>
|
|
</xpath>
|
|
<xpath expr="//div[@name='button_box']" position="inside">
|
|
<field name="employee_ids" invisible="1"/>
|
|
<button name="%(hr_attendance_action_employee)d"
|
|
class="oe_stat_button"
|
|
icon="fa-calendar"
|
|
type="action"
|
|
context="{'search_default_employee_id': employee_ids, 'search_default_check_in_filter': '1'}"
|
|
groups="base.group_user"
|
|
help="Worked hours last month">
|
|
<div class="o_field_widget o_stat_info">
|
|
<span class="o_stat_value">
|
|
<field name="hours_last_month_display"/> Hours
|
|
</span>
|
|
<span class="o_stat_text">
|
|
Last Month
|
|
</span>
|
|
</div>
|
|
</button>
|
|
</xpath>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- employee kanban view specifically for hr_attendance (to check in/out) -->
|
|
<record id="hr_employees_view_kanban" model="ir.ui.view">
|
|
<field name="name">hr.employee.kanban</field>
|
|
<field name="model">hr.employee</field>
|
|
<field name="priority">99</field>
|
|
<field name="arch" type="xml">
|
|
<kanban class="o_hr_employee_attendance_kanban" create="false">
|
|
<field name="attendance_state"/>
|
|
<field name="hours_today"/>
|
|
<field name="id"/>
|
|
<templates>
|
|
<t t-name="kanban-box">
|
|
<div class="oe_kanban_global_click">
|
|
<div class="o_kanban_image">
|
|
<img t-att-src="kanban_image('hr.employee', 'image_128', record.id.raw_value)" alt="Employee"/>
|
|
</div>
|
|
<div class="oe_kanban_details">
|
|
<div id="textbox">
|
|
<div class="float-right" t-if="record.attendance_state.raw_value == 'checked_in'">
|
|
<span id="oe_hr_attendance_status" class="fa fa-circle oe_hr_attendance_status_green" role="img" aria-label="Available" title="Available"></span>
|
|
</div>
|
|
<div class="float-right" t-if="record.attendance_state.raw_value == 'checked_out'">
|
|
<span id="oe_hr_attendance_status" class="fa fa-circle oe_hr_attendance_status_orange"
|
|
role="img" aria-label="Not available" title="Not available">
|
|
</span>
|
|
</div>
|
|
<strong>
|
|
<field name="name"/>
|
|
</strong>
|
|
</div>
|
|
<ul>
|
|
<li t-if="record.job_id.raw_value"><field name="job_id"/></li>
|
|
<li t-if="record.work_location.raw_value"><field name="work_location"/></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</templates>
|
|
</kanban>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="hr_employee_attendance_action_kanban" model="ir.actions.act_window">
|
|
<field name="name">Employees</field>
|
|
<field name="res_model">hr.employee.public</field>
|
|
<field name="view_mode">kanban</field>
|
|
<field name="view_id" ref="hr_employees_view_kanban"/>
|
|
<field name="target">fullscreen</field>
|
|
<field name="help" type="html">
|
|
<p class="o_view_nocontent_smiling_face">
|
|
Create a new employee
|
|
</p><p>
|
|
Add a few employees to be able to select an employee here and perform his check in / check out.
|
|
To create employees go to the Employees menu.
|
|
</p>
|
|
</field>
|
|
</record>
|
|
|
|
</odoo>
|