Skip to content

Commit

Permalink
[8.0.1.0.0] hr_timesheet_attendance_schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
andhit-r committed May 27, 2018
1 parent b49573c commit b02847e
Show file tree
Hide file tree
Showing 17 changed files with 651 additions and 0 deletions.
39 changes: 39 additions & 0 deletions hr_timesheet_attendance_schedule/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

=============================
Timesheet Attendance Schedule
=============================


Installation
============

To install this module, you need to:

1. Clone the branch 8.0 of the repository https://github.com/open-synergy/opnsynid-hr
2. Add the path to this repository in your configuration (addons-path)
3. Update the module list
4. Go to menu *Setting -> Modules -> Local Modules*
5. Search For *Timesheet Attendance Schedule*
6. Install the module

Credits
=======

Contributors
------------

* Michael Viriyananda <viriyananda.michael@gmail.com>
* Andhitia Rama <andhitia.r@gmail.com>
* Nurazmi <azmimr67@gmail.com>

Maintainer
----------

.. image:: https://opensynergy-indonesia.com/logo.png
:alt: OpenSynergy Indonesia
:target: https://opensynergy-indonesia.com

This module is maintained by the OpenSynergy Indonesia.
5 changes: 5 additions & 0 deletions hr_timesheet_attendance_schedule/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
24 changes: 24 additions & 0 deletions hr_timesheet_attendance_schedule/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Timesheet Attendance Schedule",
"version": "8.0.1.0.0",
"category": "Human Resource",
"website": "https://opensynergy-indonesia.com",
"author": "OpenSynergy Indonesia",
"license": "AGPL-3",
"installable": True,
"depends": [
"hr_timesheet_sheet",
],
"data": [
"security/ir.model.access.csv",
"data/ir_filters_data.xml",
"data/ir_actions_server_data.xml",
"data/base_action_rule_data.xml",
"views/hr_timesheet_sheet_views.xml",
"views/hr_timesheet_attendance_schedule_views.xml",
"views/hr_attendance_config_setting_views.xml",
],
}
17 changes: 17 additions & 0 deletions hr_timesheet_attendance_schedule/data/base_action_rule_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 OpenSynergy Indonesia
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->

<openerp>
<data>

<record id="create_attendance_schedule_action_rule" model="base.action.rule">
<field name="name">Create Attendance Schedule</field>
<field name="model_id" ref="hr_timesheet_sheet.model_hr_timesheet_sheet_sheet"/>
<field name="kind">on_write</field>
<field name="filter_id" ref="after_attendance_schedule_filter"/>
<field name="server_action_ids" eval="[(4, ref('hr_timesheet_attendance_schedule.create_attendance_schedule_actions_server'))]"/>
</record>

</data>
</openerp>
21 changes: 21 additions & 0 deletions hr_timesheet_attendance_schedule/data/ir_actions_server_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 OpenSynergy Indonesia
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->

<openerp>
<data>

<record id="create_attendance_schedule_actions_server" model="ir.actions.server">
<field name="name">Create Attendance Schedule</field>
<field name="sequence" eval="5"/>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="hr_timesheet_sheet.model_hr_timesheet_sheet_sheet"/>
<field name="condition">True</field>
<field name="state">code</field>
<field name="code">object.action_create_attendance_schedule()</field>
</record>



</data>
</openerp>
16 changes: 16 additions & 0 deletions hr_timesheet_attendance_schedule/data/ir_filters_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 OpenSynergy Indonesia
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->

<openerp>
<data>

<record id="after_attendance_schedule_filter" model="ir.filters">
<field name="name">After Attendance Schedule Creation</field>
<field name="model_id">hr_timesheet_sheet.sheet</field>
<field name="domain">[["state","=","draft"]]</field>
<field name="active" eval="0"/>
</record>

</data>
</openerp>
9 changes: 9 additions & 0 deletions hr_timesheet_attendance_schedule/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import hr_attendance
from . import hr_timesheet_attendance_schedule
from . import hr_timesheet_sheet
from . import res_company
from . import res_config
38 changes: 38 additions & 0 deletions hr_timesheet_attendance_schedule/models/hr_attendance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from dateutil.relativedelta import relativedelta
from openerp import models, fields, api


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

@api.multi
@api.depends("name")
def _compute_schedule(self):
obj_schedule = self.env["hr.timesheet_attendance_schedule"]
for attn in self:
company = attn.employee_id.company_id
early_buffer = fields.Datetime.from_string(attn.name) + \
relativedelta(hours=company.early_attendance_buffer)
early_buffer = fields.Datetime.to_string(early_buffer)
late_buffer = fields.Datetime.from_string(attn.name) + \
relativedelta(hours=-company.late_attendance_buffer)
late_buffer = fields.Datetime.to_string(late_buffer)

criteria = [
("employee_id", "=", attn.employee_id.id),
("date_start", "<=", early_buffer),
("date_end", ">=", late_buffer),
]
schedules = obj_schedule.search(criteria, limit=1)
attn.schedule_id = schedules[0].id if len(schedules) > 0 else False

schedule_id = fields.Many2one(
string="Attendance Schedule",
comodel_name="hr.timesheet_attendance_schedule",
compute="_compute_schedule",
store=True,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openerp import models, fields, api


class HrTimesheetAttendanceSchedule(models.Model):
_name = "hr.timesheet_attendance_schedule"
_description = "Timesheet Attendance Schedule"
_order = "sheet_id, date_start"

@api.multi
@api.depends("attendance_ids")
def _compute_attendance(self):
for schedule in self:
attendances = schedule.attendance_ids.filtered(
lambda r: r.action == "sign_in").sorted(key=lambda r: r.name)
schedule.start_attendance_id = attendances[
0].id if len(attendances) > 0 else False

attendances = schedule.attendance_ids.\
filtered(lambda r: r.action == "sign_out").\
sorted(key=lambda r: r.name, reverse=True)
schedule.end_attendance_id = attendances[
0].id if len(attendances) > 0 else False

@api.multi
@api.depends(
"start_attendance_id", "end_attendance_id",
)
def _compute_state(self):
for attn in self:
if attn.start_attendance_id and \
attn.end_attendance_id:
attn.state = "present"
elif (attn.start_attendance_id and not attn.end_attendance_id) or \
(not attn.start_attendance_id and attn.end_attendance_id):
attn.state = "open"
elif not attn.start_attendance_id and \
not attn.end_attendance_id:
attn.state = "absence"

@api.multi
@api.depends(
"date_start", "date_end",
"start_attendance_id", "end_attendance_id",
"start_attendance_id.name", "end_attendance_id.name",
)
def _compute_work_hour(self):
for attn in self:
schedule_work_hour = real_work_hour = early_start_hour = \
late_start_hour = finish_early_hour = finish_late_hour = \
0.0
dt_schedule_start = fields.Datetime.from_string(attn.date_start) \
if attn.date_start else False
dt_schedule_end = fields.Datetime.from_string(attn.date_end) \
if attn.date_end else False
dt_real_start = fields.Datetime.\
from_string(attn.start_attendance_id.name) if attn.\
start_attendance_id else False
dt_real_end = fields.Datetime.\
from_string(attn.end_attendance_id.name) if attn.\
end_attendance_id else False

if dt_schedule_start and dt_schedule_end:
schedule_work_hour = \
(dt_schedule_end - dt_schedule_start).total_seconds() / \
3600.0

if dt_real_start and dt_real_end:
real_work_hour = \
(dt_real_end - dt_real_start).total_seconds() / \
3600.0

if dt_schedule_start and dt_real_start:
if dt_schedule_start > dt_real_start:
early_start_hour = (dt_schedule_start - dt_real_start).\
total_seconds() / 3600.0

if dt_schedule_start < dt_real_start:
late_start_hour = (dt_real_start - dt_schedule_start).\
total_seconds() / 3600.0

if dt_schedule_end and dt_real_end:
if dt_schedule_end > dt_real_end:
finish_early_hour = (dt_schedule_end - dt_real_end).\
total_seconds() / 3600.0

if dt_schedule_end < dt_real_end:
finish_late_hour = (dt_real_end - dt_schedule_end).\
total_seconds() / 3600.0

attn.schedule_work_hour = schedule_work_hour
attn.real_work_hour = real_work_hour
attn.early_start_hour = early_start_hour
attn.late_start_hour = late_start_hour
attn.finish_early_hour = finish_early_hour
attn.finish_late_hour = finish_late_hour

sheet_id = fields.Many2one(
string="Timesheet",
comodel_name="hr_timesheet_sheet.sheet",
)
employee_id = fields.Many2one(
string="Employee",
related="sheet_id.employee_id",
store=True,
)
date_start = fields.Datetime(
string="Date Start",
required=False,
)
date_end = fields.Datetime(
string="Date End",
required=False,
)
attendance_ids = fields.One2many(
string="Attendances",
comodel_name="hr.attendance",
inverse_name="schedule_id",
)
start_attendance_id = fields.Many2one(
string="Start Attendance",
comodel_name="hr.attendance",
compute="_compute_attendance",
store=True,
)
end_attendance_id = fields.Many2one(
string="End Attendance",
comodel_name="hr.attendance",
compute="_compute_attendance",
store=True,
)
real_date_start = fields.Datetime(
string="Real Date Start",
related="start_attendance_id.name",
)
real_date_end = fields.Datetime(
string="Real Date End",
related="end_attendance_id.name",
)

state = fields.Selection(
string="State",
selection=[
("absence", "Absence"),
("open", "Open"),
("present", "Present"),
],
default="absence",
required=True,
compute="_compute_state",
store=True,
)
schedule_work_hour = fields.Float(
string="Schedule Work Hour",
compute="_compute_work_hour",
store=True,
)
real_work_hour = fields.Float(
string="Real Work Hour",
compute="_compute_work_hour",
store=True,
)
early_start_hour = fields.Float(
string="Early Start",
compute="_compute_work_hour",
store=True,
)
late_start_hour = fields.Float(
string="Late Start",
compute="_compute_work_hour",
store=True,
)
finish_early_hour = fields.Float(
string="Finish Early",
compute="_compute_work_hour",
store=True,
)
finish_late_hour = fields.Float(
string="Finish Late",
compute="_compute_work_hour",
store=True,
)
Loading

0 comments on commit b02847e

Please sign in to comment.