diff --git a/project_subtask/static/description/Icon.png b/project_subtask/static/description/icon.png similarity index 100% rename from project_subtask/static/description/Icon.png rename to project_subtask/static/description/icon.png diff --git a/workload_in_project/__init__.py b/workload_in_project/__init__.py new file mode 100644 index 000000000..3a5f9a400 --- /dev/null +++ b/workload_in_project/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2016-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import models + diff --git a/workload_in_project/__openerp__.py b/workload_in_project/__openerp__.py new file mode 100644 index 000000000..a1208ad4c --- /dev/null +++ b/workload_in_project/__openerp__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2016-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'Workload In Project', + 'version': '9.0.1.0.0', + 'summary': """Calculate The Workload For Employees In Project""", + 'description': 'This module helps you to calculate workload for employees', + 'category': 'Project Management', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': "http://www.cybrosys.com", + 'depends': ['base', 'project'], + 'data': [ + 'views/employee_workload_report_view.xml', + 'reports/employee_workload_report.xml', + ], + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'demo': [], + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/workload_in_project/models/__init__.py b/workload_in_project/models/__init__.py new file mode 100644 index 000000000..b168ba5c0 --- /dev/null +++ b/workload_in_project/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2016-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import employee_workload_calc +import employee_workload_parser + diff --git a/workload_in_project/models/employee_workload_calc.py b/workload_in_project/models/employee_workload_calc.py new file mode 100644 index 000000000..bd8a970be --- /dev/null +++ b/workload_in_project/models/employee_workload_calc.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2016-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +from openerp import models, fields, api, _ + + +class ResUsersInherit(models.Model): + _inherit = 'res.users' + + progress_rate = fields.Integer(string='Workload') + maximum_rate = fields.Integer(default=100) + + def fields_view_get(self, cr, uid, view_id=None, view_type='kanban', context=None, toolbar=False, submenu=False): + ret_val = super(ResUsersInherit, self).fields_view_get( + cr, uid, view_id=view_id, view_type=view_type, context=context, + toolbar=toolbar, submenu=submenu) + obj = self.pool.get('res.users').search(cr, uid, []) + for each in obj: + workload_hrs = 0.0 + workload_perc = 0.0 + ir_values = self.pool.get('ir.values') + no_of_days = ir_values.get_default(cr, uid, 'project.config.settings', 'no_of_days') + no_of_hrs = ir_values.get_default(cr, uid, 'project.config.settings', 'working_hr') + user_obj = self.pool.get('res.users').browse(cr, uid, each) + if no_of_days: + to_date = datetime.today() + timedelta(days=no_of_days) + else: + to_date = datetime.today() + timedelta(days=6) + obj1 = self.pool.get('project.task').search(cr, uid, + [('user_id', '=', user_obj.id), + ('date_deadline', '>=', fields.Date.today()), + ('date_deadline', '<=', to_date)]) + for each1 in obj1: + task_obj = self.pool.get('project.task').browse(cr, uid, each1) + time_now = fields.Date.from_string(fields.Date.today()) + deadline = fields.Date.from_string(task_obj.date_deadline) + workload = relativedelta(deadline, time_now) + workload_hrs = workload_hrs + workload.days + start_date = fields.Date.from_string(fields.Date.today()) + end_date1 = to_date.strftime('%Y-%m-%d') + end_date = fields.Date.from_string(end_date1) + no_of_days1 = relativedelta(end_date, start_date) + if no_of_hrs: + maximum_workload = no_of_hrs * no_of_days1.days + else: + maximum_workload = 8 * no_of_days1.days + workload_perc = (workload_hrs / maximum_workload) * 100 + user_obj.write({'maximum_rate': 100, + 'progress_rate': workload_perc}) + return ret_val + + +class ProjectSettings(models.Model): + _inherit = 'project.config.settings' + + working_hr = fields.Integer(string='Working Hr/day', default=8) + no_of_days = fields.Integer(string='No of days for calculation', default=6) + block_busy_users = fields.Boolean(string='Block busy users ?', default=False) + + @api.multi + def set_block_busy_users(self): + return self.env['ir.values'].sudo().set_default( + 'project.config.settings', 'block_busy_users', self.block_busy_users) + + @api.multi + def set_working_hr(self): + return self.env['ir.values'].sudo().set_default( + 'project.config.settings', 'working_hr', self.working_hr) + + @api.multi + def set_no_of_days(self): + return self.env['ir.values'].sudo().set_default( + 'project.config.settings', 'no_of_days', self.no_of_days) + + +class ProjectInherit(models.Model): + _inherit = 'project.task' + + @api.constrains('user_id') + def validation(self): + ir_values = self.pool.get('ir.values') + block_users = ir_values.get_default(self._cr, self._uid, 'project.config.settings', 'block_busy_users') + if block_users: + if self.user_id.progress_rate > 80: + raise Warning(_('%s is %s percentage Overloaded with Work') % (self.user_id.name, self.user_id.progress_rate)) + + +class EmployeeWorkloadReport(models.TransientModel): + _name = "wizard.workload.report" + _description = "Employee Workload Report" + + working_hr = fields.Integer(string='Working Hr/day', required=True, default=8) + from_date = fields.Date(string='From Date', required=True) + to_date = fields.Date(string='To Date', required=True) + + _defaults = { + 'from_date': lambda *a: datetime.now().strftime('%Y-%m-%d'), + 'to_date': datetime.today() + timedelta(days=6) + } + + @api.multi + def workload_report(self): + data = self.read()[0] + datas = { + 'ids': [], + 'model': 'wizard.workload.report', + 'form': data + } + return self.env['report'].get_action(self, 'workload_in_project.report_employee_workload', data=datas) + diff --git a/workload_in_project/models/employee_workload_parser.py b/workload_in_project/models/employee_workload_parser.py new file mode 100644 index 000000000..2df56792f --- /dev/null +++ b/workload_in_project/models/employee_workload_parser.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2016-TODAY Cybrosys Technologies(). +# Author: Jesni Banu() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from dateutil.relativedelta import relativedelta +from openerp.report import report_sxw +from openerp.osv import osv +from openerp import fields + + +class EmployeeWorkloadReportCommon(report_sxw.rml_parse): + + def __init__(self, cr, uid, name, context=None): + super(EmployeeWorkloadReportCommon, self).__init__(cr, uid, name, context=context) + self.localcontext.update({ + 'get_mxm_workload': self.get_mxm_workload, + 'get_line': self.get_lines, + }) + self.context = context + + def get_mxm_workload(self, data): + start_date = fields.Date.from_string(data['form']['from_date']) + end_date = fields.Date.from_string(data['form']['to_date']) + no_of_days = relativedelta(end_date, start_date) + maximum_workload = data['form']['working_hr'] * no_of_days.days + return maximum_workload + + def get_lines(self, data): + obj = self.pool.get('res.users').search(self.cr, self.uid, []) + lines = [] + for each in obj: + workload_hrs = 0.0 + workload_perc = 0.0 + user_obj = self.pool.get('res.users').browse(self.cr, self.uid, each) + obj1 = self.pool.get('project.task').search(self.cr, self.uid, + [('user_id', '=', user_obj.id), + ('date_deadline', '>=', data['form']['from_date']), + ('date_deadline', '<=', data['form']['to_date'])]) + for each1 in obj1: + task_obj = self.pool.get('project.task').browse(self.cr, self.uid, each1) + time_now = fields.Date.from_string(fields.Date.today()) + deadline = fields.Date.from_string(task_obj.date_deadline) + workload = relativedelta(deadline, time_now) + workload_hrs = workload_hrs + workload.days + maximum_workload = self.get_mxm_workload(data) + workload_perc = (workload_hrs / maximum_workload) * 100 + if workload_perc > 100: + status = 'Over Workload' + elif workload_perc > 75: + status = 'Busy' + elif workload_perc > 50: + status = 'Normal' + elif workload_perc > 0: + status = 'Less Workload' + else: + status = 'Free' + vals = { + 'employee': user_obj.name, + 'no_of_works': len(obj1), + 'workload': workload_hrs, + 'workload_perc': workload_perc, + 'status': status, + } + lines.append(vals) + return lines + + +class PrintReport(osv.AbstractModel): + _name = 'report.workload_in_project.report_employee_workload' + _inherit = 'report.abstract_report' + _template = 'workload_in_project.report_employee_workload' + _wrapped_report_class = EmployeeWorkloadReportCommon + diff --git a/workload_in_project/reports/employee_workload_report.xml b/workload_in_project/reports/employee_workload_report.xml new file mode 100644 index 000000000..596be3700 --- /dev/null +++ b/workload_in_project/reports/employee_workload_report.xml @@ -0,0 +1,66 @@ + + + + + + diff --git a/workload_in_project/static/description/banner.jpg b/workload_in_project/static/description/banner.jpg new file mode 100644 index 000000000..93f52991e Binary files /dev/null and b/workload_in_project/static/description/banner.jpg differ diff --git a/workload_in_project/static/description/cybro_logo.png b/workload_in_project/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/workload_in_project/static/description/cybro_logo.png differ diff --git a/workload_in_project/static/description/icon.png b/workload_in_project/static/description/icon.png new file mode 100644 index 000000000..4b959c709 Binary files /dev/null and b/workload_in_project/static/description/icon.png differ diff --git a/workload_in_project/static/description/index.html b/workload_in_project/static/description/index.html new file mode 100644 index 000000000..c8e81af08 --- /dev/null +++ b/workload_in_project/static/description/index.html @@ -0,0 +1,123 @@ +
+
+

Workload In Project

+

Calculate The Workload For Employees In Project

+

Author : Cybrosys Techno Solutions , www.cybrosys.com

+
+

Features:

+
    +
  •    Employee workload report.
  • +
  •    Workload progressbar in kanban view.
  • +
  •    Raise validation error while assigning task to busy users.
  • +
  •    Workload Configuration.
  • +
+
+
+
+ +
+
+

Workload Configuration

+
+
+
+ +
+
+
+

+ Users can configure the employee workload settings. Here user can give working hr/day and no of days to calculate workload. + And also user have an option to block busy users from assigning task via ticking 'Block Busy Users' field. +

+
+ +
+
+
+ +
+
+

Employee workload report

+
+
+
+ +
+
+
+

+

Project ---> Report ---> Employee Workload

+

This wizard allows you to take Employee Workload Report. Here You can give from date, to date and working hr/day. Then you will get corresponding Report.

+

+
+
+
+ +
+
+
+
+
+ +
+
+

Workload progressbar in kanban view

+
+
+
+ +
+
+
+
+

+ Here you can see workload progress bar for each users. +

+
+
+
+ +
+
+

Validation for Busy Users

+
+
+
+ +
+
+
+

+ If you tick on 'Block busy users' from configuration then the module will raise a warning when you try to assign work for busy users. +

+
+ +
+
+
+ +
+

Need Any Help?

+ +
diff --git a/workload_in_project/static/description/project_config.png b/workload_in_project/static/description/project_config.png new file mode 100644 index 000000000..e457599c3 Binary files /dev/null and b/workload_in_project/static/description/project_config.png differ diff --git a/workload_in_project/static/description/report.png b/workload_in_project/static/description/report.png new file mode 100644 index 000000000..b183bd227 Binary files /dev/null and b/workload_in_project/static/description/report.png differ diff --git a/workload_in_project/static/description/users.png b/workload_in_project/static/description/users.png new file mode 100644 index 000000000..a3edbf58d Binary files /dev/null and b/workload_in_project/static/description/users.png differ diff --git a/workload_in_project/static/description/validation1.png b/workload_in_project/static/description/validation1.png new file mode 100644 index 000000000..584fe1732 Binary files /dev/null and b/workload_in_project/static/description/validation1.png differ diff --git a/workload_in_project/static/description/wizard.png b/workload_in_project/static/description/wizard.png new file mode 100644 index 000000000..23f7b5f01 Binary files /dev/null and b/workload_in_project/static/description/wizard.png differ diff --git a/workload_in_project/views/employee_workload_report_view.xml b/workload_in_project/views/employee_workload_report_view.xml new file mode 100644 index 000000000..915a1304e --- /dev/null +++ b/workload_in_project/views/employee_workload_report_view.xml @@ -0,0 +1,114 @@ + + + + + wizard.workload.report.form + wizard.workload.report + +
+ + + + + + + + + +
+
+
+
+
+ + + Employee Workload Report + wizard.workload.report + form + form + + new + + + + res.users.kanban + res.users + + + + + + + + + + + +
+
+
+
+ + + +
+
+ +
    +
  • +
+ + +
+
+
+ + + + + + + + project settings + project.config.settings + + + + + + + + + + + + + + Project Users + ir.actions.act_window + res.users + form + kanban + + + + + + + + + + + \ No newline at end of file