Skip to content

Commit

Permalink
Merge commit 'refs/pull/95/head' of github.com:acsone/acsone-addons i…
Browse files Browse the repository at this point in the history
…nto lih_master
  • Loading branch information
adrienpeiffer committed Mar 7, 2016
2 parents 0c61510 + 6587d9f commit 679f443
Show file tree
Hide file tree
Showing 8 changed files with 451 additions and 0 deletions.
26 changes: 26 additions & 0 deletions hr_holidays_working_time/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.. 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

========================
HR holidays working time
========================

This module was written to compute the duration of a leave request from the employee working time.

Credits
=======

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

* Adrien Peiffer <adrien.peiffer@acsone.eu>

Maintainer
----------

.. image:: https://www.acsone.eu/logo.png
:alt: ACSONE SA/NV
:target: http://www.acsone.eu

This module is maintained by ACSONE SA/NV.
2 changes: 2 additions & 0 deletions hr_holidays_working_time/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import models
43 changes: 43 additions & 0 deletions hr_holidays_working_time/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# This file is part of hr_holidays_working_time,
# an Odoo module.
#
# Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
#
# hr_holidays_working_time is free software:
# you can redistribute it and/or modify it under the terms of the GNU
# Affero General Public License as published by the Free Software
# Foundation,either version 3 of the License, or (at your option) any
# later version.
#
# hr_holidays_working_time is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with hr_holidays_working_time.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "HR holidays working time",

'summary': """
Compute duration of leaves from the employee's working time""",
'author': 'ACSONE SA/NV',
'website': "http://acsone.eu",
'category': 'Human resources',
'version': '8.0.1.0.0',
'license': 'AGPL-3',
'depends': [
'hr',
'hr_holidays',
'hr_employee_current_contract',
],
'data': [
'views/hr_holidays_view.xml',
],
}
2 changes: 2 additions & 0 deletions hr_holidays_working_time/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import hr_holidays
134 changes: 134 additions & 0 deletions hr_holidays_working_time/models/hr_holidays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# This file is part of hr_holidays_working_time,
# an Odoo module.
#
# Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
#
# hr_holidays_working_time is free software:
# you can redistribute it and/or modify it under the terms of the GNU
# Affero General Public License as published by the Free Software
# Foundation,either version 3 of the License, or (at your option) any
# later version.
#
# hr_holidays_working_time is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with hr_holidays_working_time.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp import models, api, fields
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from datetime import datetime, timedelta
from dateutil import rrule


class HrHolidays(models.Model):
_inherit = 'hr.holidays'

number_of_hours_temp = fields.Float('Allocation Hours')
number_of_hours = fields.Float(
'Allocation Hours', compute='_compute_number_of_hours', store=True)
number_of_days_temp = fields.Float(
compute='_compute_number_of_hours_from_hours', store=True)

@api.model
def _get_day_to_hours_factor(self):
return 8.0

@api.one
@api.depends('number_of_hours_temp')
def _compute_number_of_hours_from_hours(self):
if self.number_of_hours_temp:
self.number_of_days_temp = \
self.number_of_hours_temp / self._get_day_to_hours_factor()
else:
self.number_of_days_temp = 0

@api.one
@api.depends('type', 'number_of_hours_temp')
def _compute_number_of_hours(self):
if self.type == 'remove':
self.number_of_hours = - self.number_of_hours_temp
else:
self.number_of_hours = self.number_of_hours_temp

@api.multi
def _get_duration_from_working_time(self, date_to, date_from, employee_id):
if employee_id:
employee = self.env['hr.employee'].sudo().browse([employee_id])
if employee.id:
contract_obj = self.env['hr.contract']
start_dt = datetime.strptime(date_from,
DEFAULT_SERVER_DATETIME_FORMAT)
end_dt = datetime.strptime(date_to,
DEFAULT_SERVER_DATETIME_FORMAT)
hours = 0.0
for day in rrule.rrule(
rrule.DAILY, dtstart=start_dt,
until=(end_dt + timedelta(days=1))
.replace(hour=0, minute=0, second=0),
byweekday=[0, 1, 2, 3, 4, 5, 6]):
day_start_dt = day.replace(hour=0, minute=0, second=0)
day_str = fields.Date.to_string(day_start_dt)
current_contract_id =\
employee.sudo()._get_current_contract(day_str)
if not current_contract_id:
return False
current_contract =\
contract_obj.sudo().browse([current_contract_id])
working_time = current_contract.working_hours
if not working_time.id:
return False
if start_dt and day.date() == start_dt.date():
day_start_dt = start_dt
day_end_dt = day.replace(hour=23, minute=59, second=59)
if end_dt and day.date() == end_dt.date():
day_end_dt = end_dt
hours += working_time.get_working_hours_of_date(
start_dt=day_start_dt, end_dt=day_end_dt,
compute_leaves=True, resource_id=None,
default_interval=None)[0]
return hours
return False

@api.multi
def onchange_employee(self, employee_id):
res = super(HrHolidays, self).onchange_employee(employee_id)
date_from = self.env.context.get('date_from')
date_to = self.env.context.get('date_to')
if (date_to and date_from) and (date_from <= date_to):
duration = self._get_duration_from_working_time(
date_to, date_from, employee_id)
res['value']['number_of_hours_temp'] = duration
return res

@api.multi
def onchange_date_from(self, date_to, date_from):
res = super(HrHolidays, self).onchange_date_from(date_to, date_from)
if date_from and not date_to:
date_to = res['value']['date_to']
if (date_to and date_from) and (date_from <= date_to):
employee_id = self.env.context.get('employee_id', False)
if employee_id:
duration = self._get_duration_from_working_time(
date_to, date_from, employee_id)
res['value']['number_of_hours_temp'] = duration
return res

@api.multi
def onchange_date_to(self, date_to, date_from):
res = super(HrHolidays, self).onchange_date_to(date_to, date_from)
if (date_to and date_from) and (date_from <= date_to):
employee_id = self.env.context.get('employee_id', False)
if employee_id:
duration = self._get_duration_from_working_time(
date_to, date_from, employee_id)
res['value']['number_of_hours_temp'] = duration
return res
2 changes: 2 additions & 0 deletions hr_holidays_working_time/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_hr_holidays_working_time
170 changes: 170 additions & 0 deletions hr_holidays_working_time/tests/test_hr_holidays_working_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# This file is part of hr_holidays_working_time,
# an Odoo module.
#
# Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
#
# hr_holidays_working_time is free software:
# you can redistribute it and/or modify it under the terms of the GNU
# Affero General Public License as published by the Free Software
# Foundation,either version 3 of the License, or (at your option) any
# later version.
#
# hr_holidays_working_time is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with hr_holidays_working_time.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.tests import common
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT,\
DEFAULT_SERVER_DATETIME_FORMAT
from datetime import datetime, timedelta
from openerp import fields
import pytz


def create_simple_contract(self, employee, date_start, date_end=False):
vals = {
'name': 'Test',
'employee_id': employee.id,
'date_start': date_start,
'date_end': date_end,
'wage': 1.0,
}
return self.contract_obj.create(vals)


def create_resource_leave(self, date_from, date_to, calendar_id):
vals = {
'name': 'Test',
'date_from': date_from,
'date_to': date_to,
'calendar_id': calendar_id,
'resource_id': False,
}
return self.env['resource.calendar.leaves'].create(vals)


def create_full_working_time(self):
vals = {
'name': 'Test Full Time',
'attendance_ids': [(0, 0, {'name': 'Test0',
'dayofweek': '0',
'hour_from': 8,
'hour_to': 16}),
(0, 0, {'name': 'Test1',
'dayofweek': '1',
'hour_from': 8,
'hour_to': 16}),
(0, 0, {'name': 'Test2',
'dayofweek': '2',
'hour_from': 8,
'hour_to': 16}),
(0, 0, {'name': 'Test3',
'dayofweek': '3',
'hour_from': 8,
'hour_to': 16}),
(0, 0, {'name': 'Test4',
'dayofweek': '4',
'hour_from': 8,
'hour_to': 16})]
}
return self.calendar_obj.create(vals)


class TestHrHolidaysWorkingTime(common.TransactionCase):

def setUp(self):
super(TestHrHolidaysWorkingTime, self).setUp()
self.holidays_obj = self.env['hr.holidays']
self.employee_obj = self.env['hr.employee']
self.contract_obj = self.env['hr.contract']
self.calendar_obj = self.env['resource.calendar']
self.employee01 = self.env.ref('hr.employee_vad')
self.today = datetime.now()
# Get the first day of the current week
self.first_day_start_dt =\
self.today - timedelta(days=self.today.weekday())
self.contract01 = create_simple_contract(
self, self.employee01, self.first_day_start_dt)
self.working_time01 = create_full_working_time(self)
self.contract01.working_hours = self.working_time01
self._context = self.env['res.users'].context_get()

def test_holidays_working_time_one_day(self):
date_from_dt = self.first_day_start_dt.replace(hour=8, minute=0,
second=0)
tz_info = fields.Datetime.context_timestamp(self, date_from_dt).tzinfo
date_from_dt = date_from_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_to_dt = self.first_day_start_dt.replace(hour=16, minute=0,
second=0)
tz_info = fields.Datetime.context_timestamp(self, date_to_dt).tzinfo
date_to_dt = date_to_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_from = date_from_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
date_to = date_to_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
res = self.holidays_obj.onchange_date_to(date_to, date_from,
self.employee01.id)
self.assertEqual(res['value']['number_of_hours_temp'], 8)

def test_holidays_working_time_complete_week(self):
date_from_dt = self.first_day_start_dt.replace(hour=8, minute=0,
second=0)
tz_info = fields.Datetime.context_timestamp(self, date_from_dt).tzinfo
date_from_dt = date_from_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_to_dt = self.first_day_start_dt + timedelta(days=4)
date_to_dt = date_to_dt.replace(hour=16, minute=0, second=0)
tz_info = fields.Datetime.context_timestamp(self, date_to_dt).tzinfo
date_to_dt = date_to_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_from = date_from_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
date_to = date_to_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
res = self.holidays_obj.onchange_date_to(date_to, date_from,
self.employee01.id)
self.assertEqual(res['value']['number_of_hours_temp'], 40)

def test_holidays_working_time_weekend(self):
date_from_dt = self.first_day_start_dt + timedelta(days=5)
date_from_dt = date_from_dt.replace(hour=8, minute=0, second=0)
tz_info = fields.Datetime.context_timestamp(self, date_from_dt).tzinfo
date_from_dt = date_from_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_to_dt = self.first_day_start_dt + timedelta(days=6)
date_to_dt = date_to_dt.replace(hour=16, minute=0, second=0)
tz_info = fields.Datetime.context_timestamp(self, date_to_dt).tzinfo
date_to_dt = date_to_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_from = date_from_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
date_to = date_to_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
res = self.holidays_obj.onchange_date_to(date_to, date_from,
self.employee01.id)
self.assertEqual(res['value']['number_of_hours_temp'], 0)

def test_holidays_working_time_leave(self):
date_from_dt = self.first_day_start_dt.replace(hour=8, minute=0,
second=0)
tz_info = fields.Datetime.context_timestamp(self, date_from_dt).tzinfo
date_from_dt = date_from_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_to_dt = self.first_day_start_dt.replace(hour=16, minute=0,
second=0)
tz_info = fields.Datetime.context_timestamp(self, date_to_dt).tzinfo
date_to_dt = date_to_dt.replace(tzinfo=tz_info)\
.astimezone(pytz.UTC).replace(tzinfo=None)
date_from = date_from_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
date_to = date_to_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
# I create a resource leave
create_resource_leave(self, date_from, date_to, self.working_time01.id)
res = self.holidays_obj.onchange_date_to(date_to, date_from,
self.employee01.id)
self.assertEqual(res['value']['number_of_hours_temp'], 0)

0 comments on commit 679f443

Please sign in to comment.