diff --git a/hr_holidays_usability/__init__.py b/hr_holidays_usability/__init__.py
index da27bbf..0b8dc8c 100644
--- a/hr_holidays_usability/__init__.py
+++ b/hr_holidays_usability/__init__.py
@@ -22,3 +22,4 @@
from . import hr_holidays
from . import wizard
+from . import report
diff --git a/hr_holidays_usability/__openerp__.py b/hr_holidays_usability/__openerp__.py
index a053733..1362a6e 100644
--- a/hr_holidays_usability/__openerp__.py
+++ b/hr_holidays_usability/__openerp__.py
@@ -33,9 +33,14 @@
'depends': ['hr_holidays', 'hr_public_holidays'],
'data': [
'wizard/hr_holidays_mass_allocation_view.xml',
+ 'wizard/hr_holidays_post_view.xml',
+ 'report/hr_holidays_employee_counter_view.xml',
'hr_holidays_view.xml',
'hr_holidays_mail.xml',
'res_company_view.xml',
+ 'hr_employee_view.xml',
+ 'security/holiday_security.xml',
+ 'security/ir.model.access.csv',
],
'installable': True,
}
diff --git a/hr_holidays_usability/hr_employee_view.xml b/hr_holidays_usability/hr_employee_view.xml
new file mode 100644
index 0000000..c0dd981
--- /dev/null
+++ b/hr_holidays_usability/hr_employee_view.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ hr_holidays_usability.hr.employee.form
+ hr.employee
+
+
+
+ 1
+
+
+
+
+
+
diff --git a/hr_holidays_usability/hr_holidays.py b/hr_holidays_usability/hr_holidays.py
index 8510a22..1c968a3 100644
--- a/hr_holidays_usability/hr_holidays.py
+++ b/hr_holidays_usability/hr_holidays.py
@@ -71,18 +71,7 @@ class HrHolidays(orm.Model):
# 1 for 'unpaid leaves' + repos compensateur + congés conventionnels + maladie
# 1 or 2 for normal holidays
- def _compute_number_of_days(self, cr, uid, ids, name, args, context=None):
- result = {}
- for hol in self.browse(cr, uid, ids, context=context):
- if hol.type == 'remove':
- # read number_of_days_remove instead of number_of_days_temp
- result[hol.id] = -hol.number_of_days_remove
- else:
- # for allocations, we read the native field number_of_days_temp
- result[hol.id] = hol.number_of_days_temp
- return result
-
- def _compute_number_of_days_remove(
+ def _compute_number_of_days(
self, cr, uid, ids, name, args, context=None):
res = {}
# depend on the holiday_status_id
@@ -148,7 +137,18 @@ class HrHolidays(orm.Model):
break
date_dt += relativedelta(days=1)
- res[hol.id] = days
+ if hol.type == 'remove':
+ # read number_of_days_remove instead of number_of_days_temp
+ res[hol.id] = {
+ 'number_of_days': days * -1,
+ 'number_of_days_remove': days,
+ }
+ else:
+ # for allocations, we read the native field number_of_days_temp
+ res[hol.id] = {
+ 'number_of_days': hol.number_of_days_temp,
+ 'number_of_days_remove': 0,
+ }
return res
def _compute_current_leaves(self, cr, uid, ids, name, arg, context=None):
@@ -201,12 +201,13 @@ class HrHolidays(orm.Model):
help="For example, if you leave one full calendar week, "
"the end of vacation is Friday Evening"),
'number_of_days_remove': fields.function(
- _compute_number_of_days_remove,
- string="Number of Days of Vacation",
+ _compute_number_of_days,
+ string="Number of Days of Vacation", multi='holdays',
type="float", readonly=True),
# number_of_days is a native field that I inherit
'number_of_days': fields.function(
- _compute_number_of_days, string='Number of Days', store=True),
+ _compute_number_of_days, string='Number of Days',
+ multi='holdays', store=True),
'current_leaves_taken': fields.function(
_compute_current_leaves, string='Current Leaves Taken',
multi='usability', type='float', readonly=True),
@@ -218,7 +219,8 @@ class HrHolidays(orm.Model):
multi='usability', type='float', readonly=True),
'limit': fields.related(
'holiday_status_id', 'limit', type='boolean',
- string='Allow to Override Limit')
+ string='Allow to Override Limit'),
+ 'posted_date': fields.date('Posted Date', track_visibility='onchange'),
}
_defaults = {
diff --git a/hr_holidays_usability/hr_holidays_mail.xml b/hr_holidays_usability/hr_holidays_mail.xml
index 54f9e26..985a8ed 100644
--- a/hr_holidays_usability/hr_holidays_mail.xml
+++ b/hr_holidays_usability/hr_holidays_mail.xml
@@ -84,7 +84,7 @@ self.pool.get('email.template').send_mail(cr, uid, template_id, object.id, force
Start date : ${object.vacation_date_from or ''} ${object.vacation_time_from or ''}
End date : ${object.vacation_date_to or ''} ${object.vacation_time_to or ''}
% endif
-Number of days : ${object.number_of_days or '0'}
+Number of days : ${object.number_of_days < 0 and object.number_of_days * -1 or object.number_of_days}
Leave type : ${object.holiday_status_id.name or ''}
Description : ${object.name or ''}
% if object.notes:
diff --git a/hr_holidays_usability/hr_holidays_view.xml b/hr_holidays_usability/hr_holidays_view.xml
index a7a9718..426f99b 100644
--- a/hr_holidays_usability/hr_holidays_view.xml
+++ b/hr_holidays_usability/hr_holidays_view.xml
@@ -35,7 +35,7 @@
-
+
@@ -54,6 +54,9 @@
+
+
+
@@ -66,7 +69,7 @@
1
-
+
1
@@ -85,6 +88,9 @@
0
+
+
+
diff --git a/hr_holidays_usability/report/__init__.py b/hr_holidays_usability/report/__init__.py
new file mode 100644
index 0000000..ac96859
--- /dev/null
+++ b/hr_holidays_usability/report/__init__.py
@@ -0,0 +1,2 @@
+# -*- encoding: utf-8 -*-
+from . import hr_holidays_employee_counter
diff --git a/hr_holidays_usability/report/hr_holidays_employee_counter.py b/hr_holidays_usability/report/hr_holidays_employee_counter.py
new file mode 100644
index 0000000..dbf77c6
--- /dev/null
+++ b/hr_holidays_usability/report/hr_holidays_employee_counter.py
@@ -0,0 +1,71 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# HR Holidays Usability module for Odoo
+# Copyright (C) 2015 Akretion (http://www.akretion.com)
+# @author Alexis de Lattre
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
+#
+##############################################################################
+
+from openerp import tools
+from openerp.osv import fields, orm
+
+
+class HrHolidaysEmployeeCounter(orm.Model):
+ _name = 'hr.holidays.employee.counter'
+ _description = 'Counters for holidays of employees'
+ _auto = False
+ _rec_name = 'employee_id'
+ _order = 'employee_id'
+
+ _columns = {
+ 'employee_id': fields.many2one('hr.employee', "Employee"),
+ 'holiday_status_id': fields.many2one(
+ "hr.holidays.status", "Leave Type"),
+ 'current_leaves_taken': fields.float('Current Leaves Taken'),
+ 'current_remaining_leaves': fields.float('Current Remaining Leaves'),
+ 'total_allocated_leaves': fields.float('Total Allocated Leaves'),
+ }
+
+ def init(self, cr):
+ tools.drop_view_if_exists(cr, 'hr_holidays_employee_counter')
+ cr.execute("""
+ CREATE or REPLACE view hr_holidays_employee_counter AS (
+ SELECT
+ min(hh.id) AS id,
+ hh.employee_id AS employee_id,
+ hh.holiday_status_id AS holiday_status_id,
+ sum(
+ CASE WHEN hh.type='remove'
+ THEN hh.number_of_days * -1
+ ELSE 0
+ END) AS current_leaves_taken,
+ sum(hh.number_of_days) AS current_remaining_leaves,
+ sum(
+ CASE WHEN hh.type = 'add'
+ THEN hh.number_of_days
+ ELSE 0
+ END) AS total_allocated_leaves
+ FROM
+ hr_holidays hh
+ JOIN hr_holidays_status hhs
+ ON (hhs.id=hh.holiday_status_id)
+ WHERE
+ hh.state='validate' AND
+ hhs.limit=False
+ GROUP BY hh.employee_id, hh.holiday_status_id
+ )
+ """)
diff --git a/hr_holidays_usability/report/hr_holidays_employee_counter_view.xml b/hr_holidays_usability/report/hr_holidays_employee_counter_view.xml
new file mode 100644
index 0000000..b628812
--- /dev/null
+++ b/hr_holidays_usability/report/hr_holidays_employee_counter_view.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+ hr.holidays.employee.counter.tree
+ hr.holidays.employee.counter
+
+
+
+
+
+
+
+
+
+
+
+
+ hr.holidays.employee.counter.search
+ hr.holidays.employee.counter
+
+
+
+
+
+
+
+
+
+
+
+
+ Counters
+ hr.holidays.employee.counter
+ tree
+ {'hr_holidays_employee_counter_tree_main_view': 1}
+
+
+
+
+
+
+
diff --git a/hr_holidays_usability/security/holiday_security.xml b/hr_holidays_usability/security/holiday_security.xml
new file mode 100644
index 0000000..8b7ca43
--- /dev/null
+++ b/hr_holidays_usability/security/holiday_security.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Personal Holiday Counters
+
+ ['|',('employee_id.user_id','=',user.id),('employee_id.user_id','=',False)]
+
+
+
+ All Holiday Counters
+
+ [(1,'=',1)]
+
+
+
+
+
diff --git a/hr_holidays_usability/security/ir.model.access.csv b/hr_holidays_usability/security/ir.model.access.csv
new file mode 100644
index 0000000..26f7dac
--- /dev/null
+++ b/hr_holidays_usability/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_hr_holidays_employee_counter,Full access on hr.holidays.employee.counter,model_hr_holidays_employee_counter,base.group_user,1,1,1,1
diff --git a/hr_holidays_usability/wizard/__init__.py b/hr_holidays_usability/wizard/__init__.py
index e887a00..07d448e 100644
--- a/hr_holidays_usability/wizard/__init__.py
+++ b/hr_holidays_usability/wizard/__init__.py
@@ -1,2 +1,3 @@
# -*- encoding: utf-8 -*-
from . import hr_holidays_mass_allocation
+from . import hr_holidays_post
diff --git a/hr_holidays_usability/wizard/hr_holidays_post.py b/hr_holidays_usability/wizard/hr_holidays_post.py
new file mode 100644
index 0000000..f725a28
--- /dev/null
+++ b/hr_holidays_usability/wizard/hr_holidays_post.py
@@ -0,0 +1,103 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# HR Holidays Usability module for Odoo
+# Copyright (C) 2015 Akretion (http://www.akretion.com)
+# @author Alexis de Lattre
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+from openerp.tools.translate import _
+
+
+class HrHolidaysPost(orm.TransientModel):
+ _name = 'hr.holidays.post'
+ _description = 'Wizard for post holidays'
+
+ _columns = {
+ 'before_date': fields.date(
+ 'Select Holidays That Ended Before', required=True,
+ help="The wizard will select the validated holidays "
+ "that ended before that date (including holidays that "
+ "ended on that date)."),
+ 'holidays_to_post_ids': fields.many2many(
+ 'hr.holidays', string='Leave Requests to Post',
+ domain=[
+ ('type', '=', 'remove'),
+ ('holiday_type', '=', 'employee'),
+ ('state', '=', 'validate'),
+ ('posted_date', '=', False),
+ ]),
+ 'state': fields.selection([
+ ('draft', 'Draft'),
+ ('done', 'Done'),
+ ], 'State', readonly=True),
+ }
+
+ _defaults = {
+ 'before_date': fields.date.context_today,
+ 'state': 'draft',
+ }
+
+ def select_date(self, cr, uid, ids, context=None):
+ assert len(ids) == 1, 'Only 1 ID'
+ wiz = self.browse(cr, uid, ids[0], context=context)
+ hol_ids = self.pool['hr.holidays'].search(cr, uid, [
+ ('type', '=', 'remove'),
+ ('holiday_type', '=', 'employee'),
+ ('state', '=', 'validate'),
+ ('posted_date', '=', False),
+ ('vacation_date_to', '<=', wiz.before_date),
+ ], context=context)
+ self.write(cr, uid, ids, {
+ 'state': 'done',
+ 'holidays_to_post_ids': [(6, 0, hol_ids)],
+ }, context=context)
+ act_model, act_id = self.pool['ir.model.data'].get_object_reference(
+ cr, uid, 'hr_holidays_usability', 'hr_holidays_post_action')
+ assert act_model == 'ir.actions.act_window', 'Wrong model'
+ action = self.pool[act_model].read(
+ cr, uid, act_id, context=context)
+ action['res_id'] = ids[0]
+ return action
+
+ def run(self, cr, uid, ids, context=None):
+ assert len(ids) == 1, 'Only 1 ID'
+ wiz = self.browse(cr, uid, ids[0], context=context)
+ today = fields.date.context_today(self, cr, uid, context=context)
+ if not wiz.holidays_to_post_ids:
+ raise orm.except_orm(
+ _('Error:'),
+ _('No for the number of days.'))
+ hol_ids = self.read(
+ cr, uid, ids[0], context=context)['holidays_to_post_ids']
+ self.pool['hr.holidays'].write(
+ cr, uid, hol_ids,
+ {'posted_date': today}, context=context)
+ # On v8, return a graph view !
+ act_model, act_id = self.pool['ir.model.data'].get_object_reference(
+ cr, uid, 'hr_holidays', 'open_ask_holidays')
+ assert act_model == 'ir.actions.act_window', 'Wrong model'
+ action = self.pool[act_model].read(
+ cr, uid, act_id, context=context)
+ action.update({
+ 'target': 'current',
+ 'domain': [('id', 'in', hol_ids)],
+ 'nodestroy': True,
+ 'context': {'group_by': ['employee_id', 'holiday_status_id']},
+ })
+ return action
diff --git a/hr_holidays_usability/wizard/hr_holidays_post_view.xml b/hr_holidays_usability/wizard/hr_holidays_post_view.xml
new file mode 100644
index 0000000..eebfe24
--- /dev/null
+++ b/hr_holidays_usability/wizard/hr_holidays_post_view.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+ hr_holidays_post_form
+ hr.holidays.post
+
+
+
+
+
+
+ Post Leave Requests
+ hr.holidays.post
+ form
+ new
+
+
+
+
+
+