Skip to content

Commit

Permalink
Merge PR #611 into 12.0
Browse files Browse the repository at this point in the history
Signed-off-by gurneyalex
  • Loading branch information
OCA-git-bot committed Oct 22, 2019
2 parents b3307a1 + 19f11ee commit 7f1f0af
Show file tree
Hide file tree
Showing 19 changed files with 744 additions and 0 deletions.
2 changes: 2 additions & 0 deletions hr_attendance_autoclose/__init__.py
@@ -0,0 +1,2 @@
from . import models
from . import tests
23 changes: 23 additions & 0 deletions hr_attendance_autoclose/__manifest__.py
@@ -0,0 +1,23 @@
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

{
'name': 'HR Attendance Auto Close',
'version': '12.0.1.0.0',
'category': 'Human Resources',
'summary': 'Close stale Attendances',
'website': 'https://github.com/OCA/hr',
'author': 'Odoo Community Association (OCA)',
'license': 'AGPL-3',
'installable': True,
'depends': [
'hr_attendance_reason',
],
'data': [
'views/hr_employee.xml',
'data/hr_attendance_reason.xml',
'data/hr_attendance.xml',
'views/hr_attendance_view.xml',
'views/res_company_view.xml',
],
}
16 changes: 16 additions & 0 deletions hr_attendance_autoclose/data/hr_attendance.xml
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record model="ir.cron" id="check_attendance_cron">
<field name="name">Check Attendance</field>
<field name="interval_number">1</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field name="nextcall" eval="(DateTime.now() + timedelta(minutes=60)).strftime('%Y-%m-%d %H:05:00')"/>
<field name="doall" eval="True"/>
<field name="model_id" ref="hr_attendance.model_hr_attendance"/>
<field name="state">code</field>
<field name="code">
model.check_for_incomplete_attendances()
</field>
</record>
</odoo>
8 changes: 8 additions & 0 deletions hr_attendance_autoclose/data/hr_attendance_reason.xml
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="hr_attendance_reason_check_out" model="hr.attendance.reason">
<field name="name">System automatic check out due to inactivity</field>
<field name="code">S-CO</field>
<field name="action_type">sign_out</field>
</record>
</odoo>
47 changes: 47 additions & 0 deletions hr_attendance_autoclose/i18n/hr_attendance_autoclose.pot
@@ -0,0 +1,47 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * hr_attendance_autoclose
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: hr_attendance_autoclose
#: model:ir.model,name:hr_attendance_autoclose.model_hr_attendance
msgid "Attendance"
msgstr ""

#. module: hr_attendance_autoclose
#: model:ir.model.fields,field_description:hr_attendance_autoclose.field_res_company_attendance_maximum_hours_per_day
msgid "Attendance Maximum Hours Per Day"
msgstr ""

#. module: hr_attendance_autoclose
#: model:ir.ui.view,arch_db:hr_attendance_autoclose.view_company_inherit_form
msgid "Attendances"
msgstr ""

#. module: hr_attendance_autoclose
#: model:ir.actions.server,name:hr_attendance_autoclose.check_attendance_cron_ir_actions_server
#: model:ir.cron,cron_name:hr_attendance_autoclose.check_attendance_cron
#: model:ir.cron,name:hr_attendance_autoclose.check_attendance_cron
msgid "Check Attendance"
msgstr ""

#. module: hr_attendance_autoclose
#: model:ir.model,name:hr_attendance_autoclose.model_res_company
msgid "Companies"
msgstr ""

#. module: hr_attendance_autoclose
#: model:ir.model.fields,field_description:hr_attendance_autoclose.field_hr_attendance_open_worked_hours
msgid "Worked hours"
msgstr ""

3 changes: 3 additions & 0 deletions hr_attendance_autoclose/models/__init__.py
@@ -0,0 +1,3 @@
from . import hr_attendance
from . import hr_employee
from . import res_company
69 changes: 69 additions & 0 deletions hr_attendance_autoclose/models/hr_attendance.py
@@ -0,0 +1,69 @@
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import api, fields, models
from datetime import datetime
from datetime import timedelta


class HrAttendance(models.Model):
_inherit = "hr.attendance"

@api.multi
def _compute_open_worked_hours(self):
for attendance in self:
if attendance.check_out:
delta = attendance.check_out - attendance.check_in
open_worked_hours = delta.total_seconds() / 3600.0
else:
delta = datetime.now() - attendance.check_in
open_worked_hours = delta.total_seconds() / 3600.0
attendance.open_worked_hours = open_worked_hours
return True

open_worked_hours = fields.Float(
string='Worked hours', compute='_compute_open_worked_hours',
)

@api.multi
def autoclose_attendance(self, reason):
self.ensure_one()
max_hours = self.employee_id.company_id. \
attendance_maximum_hours_per_day
leave_time = self.check_in + timedelta(hours=max_hours)
vals = {'check_out': leave_time}
if reason:
vals['attendance_reason_ids'] = [(4, reason.id)]
self.write(vals)

@api.multi
def needs_autoclose(self):
self.ensure_one()
max_hours = self.employee_id.company_id.\
attendance_maximum_hours_per_day
close = not self.employee_id.no_autoclose
return close and max_hours and self.open_worked_hours > max_hours

@api.model
def check_for_incomplete_attendances(self):
stale_attendances = self.search(
[('check_out', '=', False)])
reason = self.env['hr.attendance.reason'].search(
[('code', '=', 'S-CO')], limit=1)
for att in stale_attendances.filtered(lambda a: a.needs_autoclose()):
att.autoclose_attendance(reason)

@api.constrains('check_in', 'check_out', 'employee_id')
def _check_validity(self):
""" If this is an automatic checkout the constraint is invalid
as there may be old attendances not closed
"""
reason = self.env['hr.attendance.reason'].search(
[('code', '=', 'S-CO')], limit=1)
if not reason:
return super(HrAttendance, self)._check_validity()
if self.filtered(lambda att:
att.attendance_reason_ids and reason
in att.attendance_reason_ids):
return True
return super(HrAttendance, self)._check_validity()
11 changes: 11 additions & 0 deletions hr_attendance_autoclose/models/hr_employee.py
@@ -0,0 +1,11 @@
# Copyright 2019 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class HrEmployee(models.Model):

_inherit = 'hr.employee'

no_autoclose = fields.Boolean(string='Don\'t Autoclose Attendances')
11 changes: 11 additions & 0 deletions hr_attendance_autoclose/models/res_company.py
@@ -0,0 +1,11 @@
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from odoo import models, fields


class ResCompany(models.Model):
_inherit = 'res.company'

attendance_maximum_hours_per_day = fields.Float(
string='Attendance Maximum Hours Per Day',
digits=(2, 2), default=11.0)
2 changes: 2 additions & 0 deletions hr_attendance_autoclose/readme/CONTRIBUTORS.rst
@@ -0,0 +1,2 @@
* Aaron Henriquez <aheficent@eficent.com>
* Kitti U. <kittiu@ecosoft.co.th>
5 changes: 5 additions & 0 deletions hr_attendance_autoclose/readme/DESCRIPTION.rst
@@ -0,0 +1,5 @@
This module close stale attendances automatically. Without this module, when
an employee forgets to check out at the end on the day and the next day the
employee does not realize of that, then the error is propagated and all the
attendances are wrong. With this module only the attendance with the issue is
wrong, and the manager knows the system closes the attendance, not the employee
4 changes: 4 additions & 0 deletions hr_attendance_autoclose/readme/USAGE.rst
@@ -0,0 +1,4 @@
#. Go to *Settings > Company > Attendances*.
#. Set the maximum number of hours allowed for an attendance.
#. Go to *Attendances > Manage Attedances > Attendances*.
#. Attendance are autoclosed after the hours passed are bigger.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7f1f0af

Please sign in to comment.