Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] hr_attendance_validation: improve reporting storing compute val… #180

Open
wants to merge 3 commits into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions hr_attendance_validation/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,17 @@ Configuration
=============

* Ensure employee weeks are properly set
* Set `is_compensatory` on leave types to:
* reduce domain to select leave type in hr configuration
* to dispatch taken leaves on validation sheet
* Set the leave type to use by generating compensatory
hours from attendance review (to be done in hr attendance configuration)
* You can ignore some leaves in validation sheet by ticking the "Ignored in attendance validation"
hours from attendance review (to be done in hr attendance configuration).
We use to create a new type `hr.leave.type` manually each years.
* You can ignore some leaves in validation sheet by ticking the
"Ignored in attendance validation" on holidays `hr.leave.type``
(for instance it can be useful if you manage employee remote days using hr.leave
in such case you want to ignore those lines)
* configure public holidays to take care of it while computing the theoretical week time
* once all leaves and attendances has been recorded you can generate leave reviews
by setting up a cron job running every monday morning to generate the previous week
with the following code on `hr.attendance.validation.sheet` model::
Expand Down
3 changes: 2 additions & 1 deletion hr_attendance_validation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "Hr Attendance Validation",
"summary": "Employee attendance validation.",
"category": "Human Resources",
"version": "14.0.1.1.0",
"version": "14.0.1.1.1",
"license": "AGPL-3",
"author": "Pierre Verkest, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/hr-attendance",
Expand All @@ -15,6 +15,7 @@
"hr_attendance_reason",
"hr_attendance_modification_tracking",
"hr_holidays",
"hr_holidays_public",
],
"data": [
"views/assets.xml",
Expand Down
6 changes: 6 additions & 0 deletions hr_attendance_validation/data/hr_leave_type.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="hr_holidays.holiday_status_comp" model="hr.leave.type">
<field name="is_compensatory">True</field>
</record>
</odoo>
22 changes: 22 additions & 0 deletions hr_attendance_validation/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ msgstr ""
"No se puede crear una nueva asistencia para el empleado %s. La asistencia "
"para el día de la comprobación en %s ya ha sido revisada y validada."

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compensatory Leaves (hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_hour
msgid "Compensatory hour"
Expand Down Expand Up @@ -198,6 +203,11 @@ msgstr ""
"Calcular el número de líneas de presencia no marcadas como horas "
"extraordinarias"

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compute number of compensatory leaves taken (in hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__leave_hours
msgid "Compute number of leaves in hours"
Expand Down Expand Up @@ -291,11 +301,23 @@ msgstr "Horas de la Semana en Curso"
msgid "ID"
msgstr "ID (identificador)"

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid ""
"If check, taken leaves are displayed in hr attendance validation analysis "
"report."
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__ignored_in_attendance_validation
msgid "Ignored In Attendance Validation"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid "Is Compensatory"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance__is_overtime_due
msgid "Is overtime due"
Expand Down
23 changes: 23 additions & 0 deletions hr_attendance_validation/i18n/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ msgstr ""
"Ne peut pas créer cette ligne de présence (%s, %s) elle est sur une semaine "
"déjà validée par le responsable."

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compensatory Leaves (hours)"
msgstr "Congés compensatoire pris (heures)"

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_hour
msgid "Compensatory hour"
Expand Down Expand Up @@ -193,6 +198,11 @@ msgstr ""
msgid "Compute number of attendance lines not marked as overtime"
msgstr "Nombre d'heure sur plage horaire de travail."

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compute number of compensatory leaves taken (in hours)"
msgstr "Nombre d'heures compensatoires prisent sur la période (en heures)"

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__leave_hours
msgid "Compute number of leaves in hours"
Expand Down Expand Up @@ -287,11 +297,24 @@ msgstr "Heures effectuées cette semaine"
msgid "ID"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid ""
"If check, taken leaves are displayed in hr attendance validation analysis "
"report."
msgstr ""
"Si sélectionné, pris en compte dans le total d'heures compensatoire pris."

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__ignored_in_attendance_validation
msgid "Ignored In Attendance Validation"
msgstr "Ignoré dans les feuilles de revue de présences"

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid "Is Compensatory"
msgstr "Est un type de congés compensatoire"

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance__is_overtime_due
msgid "Is overtime due"
Expand Down
22 changes: 22 additions & 0 deletions hr_attendance_validation/i18n/hr_attendance_validation.pot
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ msgid ""
"check in %s has already been reviewed and validated."
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compensatory Leaves (hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_hour
msgid "Compensatory hour"
Expand Down Expand Up @@ -175,6 +180,11 @@ msgstr ""
msgid "Compute number of attendance lines not marked as overtime"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compute number of compensatory leaves taken (in hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__leave_hours
msgid "Compute number of leaves in hours"
Expand Down Expand Up @@ -266,11 +276,23 @@ msgstr ""
msgid "ID"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid ""
"If check, taken leaves are displayed in hr attendance validation analysis "
"report."
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__ignored_in_attendance_validation
msgid "Ignored In Attendance Validation"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid "Is Compensatory"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance__is_overtime_due
msgid "Is overtime due"
Expand Down
22 changes: 22 additions & 0 deletions hr_attendance_validation/i18n/it.po
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ msgstr ""
"Non si può creare una nuova presenza per il dipendente %s. La presenza per "
"il giorno di check-in %s è già stata visionata e validata."

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compensatory Leaves (hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_hour
msgid "Compensatory hour"
Expand Down Expand Up @@ -194,6 +199,11 @@ msgstr ""
msgid "Compute number of attendance lines not marked as overtime"
msgstr "Calcola numero di righe presenza non marcate come straordinario"

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__compensatory_leave_hours
msgid "Compute number of compensatory leaves taken (in hours)"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_attendance_validation_sheet__leave_hours
msgid "Compute number of leaves in hours"
Expand Down Expand Up @@ -287,11 +297,23 @@ msgstr "Ore settimana corrente"
msgid "ID"
msgstr "ID"

#. module: hr_attendance_validation
#: model:ir.model.fields,help:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid ""
"If check, taken leaves are displayed in hr attendance validation analysis "
"report."
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__ignored_in_attendance_validation
msgid "Ignored In Attendance Validation"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_leave_type__is_compensatory
msgid "Is Compensatory"
msgstr ""

#. module: hr_attendance_validation
#: model:ir.model.fields,field_description:hr_attendance_validation.field_hr_attendance__is_overtime_due
msgid "Is overtime due"
Expand Down
100 changes: 74 additions & 26 deletions hr_attendance_validation/models/hr_attendance_validation_sheet.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright 2021 Pierre Verkest
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from datetime import timedelta
from datetime import datetime, timedelta

from odoo import SUPERUSER_ID, _, api, fields, models
from odoo.osv import expression
Expand Down Expand Up @@ -69,8 +69,9 @@ def name_get(self):
)
theoretical_hours = fields.Float(
string="Theoretical (hours)",
related="calendar_id.total_hours",
help="Theoretical calendar hours to spend by week.",
compute="_compute_theoretical_hours",
store=True,
help="heoretical calendar hours to spend by week.",
)
attendance_ids = fields.One2many(
"hr.attendance", inverse_name="validation_sheet_id", string="Attendances"
Expand All @@ -96,26 +97,38 @@ def name_get(self):
leave_hours = fields.Float(
"Leaves (hours)",
compute="_compute_leaves",
store=True,
help="Compute number of leaves in hours",
)
compensatory_leave_hours = fields.Float(
"Compensatory Leaves (hours)",
compute="_compute_leaves",
store=True,
help="Compute number of compensatory leaves taken (in hours)",
)

attendance_hours = fields.Float(
"Attendance (hours)",
compute="_compute_attendances_hours",
store=True,
help="Compute number of attendance lines not marked as overtime",
)
attendance_total_hours = fields.Float(
"Total Attendance (hours)",
compute="_compute_attendances_hours",
store=True,
help="Validated attendances. Sum attendance and due overtime lines.",
)
overtime_due_hours = fields.Float(
"Overtime due (hours)",
compute="_compute_attendances_hours",
store=True,
help="Compute number of attendance lines marked as overtime which are marked as due",
)
overtime_not_due_hours = fields.Float(
"Overtime not due (hours)",
compute="_compute_attendances_hours",
store=True,
help="Compute number of attendance lines marked as overtime which are not due",
)
compensatory_hour = fields.Float(
Expand All @@ -138,33 +151,65 @@ def _onchange_recompute_lines(self):
self.ensure_one()
self.require_regeneration = True

@api.depends("leave_ids")
def _compute_leaves(self):
@api.depends("calendar_id", "date_from", "date_to")
def _compute_theoretical_hours(self):
for record in self:
leave_hours = 0
for leave in record.leave_ids:
if leave.request_unit_half or leave.request_unit_hours:
# we assume time off is recorded by hours
leave_hours += leave.number_of_hours_display
else:
# As far leaves can be record on multiple weeks
# intersect calendar attendance and leaves date
# to compute theoretical leave time
current_date = max(leave.request_date_from, record.date_from)
date_to = min(
leave.request_date_to or leave.request_date_from, record.date_to
if record.calendar_id.exists():
record.theoretical_hours = record.with_context(
employee_id=record.employee_id.id, exclude_public_holidays=True
).calendar_id.get_work_hours_count(
datetime.combine(record.date_from, datetime.min.time()),
datetime.combine(record.date_to, datetime.max.time()),
compute_leaves=False,
)
else:
record.theoretical_hours = 0

def _compute_leaves_fields(self):
self.ensure_one()

leave_hours = 0
compensatory_leave_hours = 0
for leave in self.leave_ids:
if leave.request_unit_half or leave.request_unit_hours:
# we assume time off is recorded by hours
leave_hours += leave.number_of_hours_display
if leave.holiday_status_id.is_compensatory:
compensatory_leave_hours += leave.number_of_hours_display
else:
# As far leaves can be record on multiple weeks
# intersect calendar attendance and leaves date
# to compute theoretical leave time
current_date = max(leave.request_date_from, self.date_from)
date_to = min(
leave.request_date_to or leave.request_date_from, self.date_to
)
while current_date <= date_to:
current_date_leave_hours = sum(
self.calendar_id.attendance_ids.filtered(
lambda att: int(att.dayofweek) == current_date.weekday()
).mapped(lambda att: att.hour_to - att.hour_from)
)
while current_date <= date_to:
leave_hours += sum(
record.calendar_id.attendance_ids.filtered(
lambda att: int(att.dayofweek) == current_date.weekday()
).mapped(lambda att: att.hour_to - att.hour_from)
)
current_date += timedelta(days=1)
leave_hours += current_date_leave_hours
if leave.holiday_status_id.is_compensatory:
compensatory_leave_hours += current_date_leave_hours
current_date += timedelta(days=1)
return leave_hours, compensatory_leave_hours

record.leave_hours = leave_hours
@api.depends("leave_ids", "leave_ids.holiday_status_id.is_compensatory")
def _compute_leaves(self):
for record in self:
(
record.leave_hours,
record.compensatory_leave_hours,
) = record._compute_leaves_fields()

@api.depends("attendance_ids", "attendance_ids.is_overtime")
@api.depends(
"attendance_ids",
"attendance_ids.is_overtime",
"attendance_ids.is_overtime_due",
"attendance_due_ids",
)
def _compute_attendances_hours(self):
for record in self:
record.attendance_hours = sum(
Expand All @@ -186,6 +231,9 @@ def _compute_attendances_hours(self):
record.attendance_due_ids.mapped("worked_hours")
)

@api.depends(
"attendance_ids", "attendance_ids.is_overtime", "attendance_ids.is_overtime_due"
)
def _compute_attendance_due_ids(self):
for record in self:
record.attendance_due_ids = record.attendance_ids.filtered(
Expand Down
Loading
Loading