Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

project_task_scheduling: Module for automatic task planning #419

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5578e2d
project_task_scheduling: New module for automated task scheduling
ernestotejeda Aug 3, 2018
4e5a21e
project_task_scheduling: Fix flake8 errors and fix unit test error
ernestotejeda Sep 19, 2018
07022bb
project_task_scheduling: Fix E231 flake8 error
ernestotejeda Sep 19, 2018
e83e1ce
project_task_scheduling: Use date_start and date_end for scheduling
ernestotejeda Sep 19, 2018
ba1d9f5
project_task_assignment: Update readme description
ernestotejeda Sep 20, 2018
fb3b5c7
project_task_assignment: Change module name to project_task_employee
ernestotejeda Sep 20, 2018
37ac1a5
project_task_schedule: Update dependence on project_task_employee
ernestotejeda Sep 21, 2018
02144ea
project_task_employee: Add domain to employee_id field
ernestotejeda Sep 20, 2018
560de9d
project_task_employee: Refactoring code
ernestotejeda Sep 20, 2018
e62beea
project_task_scheduling: Refactoring code
ernestotejeda Sep 22, 2018
27851be
project_task_scheduling: Improve scheduling for tasks with skill
ernestotejeda Sep 23, 2018
7841cb2
project_task_employee: Add help to fields
ernestotejeda Sep 23, 2018
129ed4e
project_task_scheduling: Add help to fields
ernestotejeda Sep 23, 2018
79045c2
project_task_scheduling: Add references to the readme
ernestotejeda Sep 23, 2018
7e637c3
project_task_scheduling: Improve USAGE section of the readme
ernestotejeda Sep 23, 2018
ab28bee
project_task_employee: Fix unite test error
ernestotejeda Sep 24, 2018
36bc972
project_task_employee: Refactoring code
ernestotejeda Sep 24, 2018
0ceb2d4
project_task_schedule: Fix the way to remove an interval from gaps
ernestotejeda Sep 25, 2018
7920b43
project_task_employee: Add unit test
ernestotejeda Sep 25, 2018
f7211b2
project_task_employee: Set task closed field store=True
ernestotejeda Sep 25, 2018
4101b4c
project_task_scheduling: Add states to proposals.
ernestotejeda Sep 25, 2018
445a350
project_task_scheduling: Change the name of a function
ernestotejeda Sep 25, 2018
05acf10
project_task_scheduling: Refactoring code
ernestotejeda Sep 25, 2018
2f74b5a
project_task_scheduling: Add copyright to files
ernestotejeda Sep 25, 2018
02b6f64
project_task_scheduling: Remove copyright line from __init__.py files
ernestotejeda Sep 26, 2018
de17f06
project_task_employee: Add copyright to files
ernestotejeda Sep 26, 2018
4ea656a
project_task_employee: Refactoring code
ernestotejeda Sep 27, 2018
cd71b48
project_task_scheduling: Refactoring code
ernestotejeda Sep 27, 2018
8b3619c
project_task_scheduling: Improve DESCRIPTION section of the readme
ernestotejeda Sep 27, 2018
608fdbe
project_task_scheduling: Remove the 'closed' field
ernestotejeda Sep 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions project_task_employee/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**This file is going to be generated by oca-gen-addon-readme.**
2 changes: 2 additions & 0 deletions project_task_employee/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models
23 changes: 23 additions & 0 deletions project_task_employee/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Project task employee",
"version": "11.0.1.0.0",
"category": "Project Management",
"author": "Tecnativa, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/project",
"license": "AGPL-3",
"depends": [
"hr",
"project",
],
"data": [
"views/project_view.xml",
"views/project_task_view.xml",
],
"demo": [
"demo/project_task.xml",
],
"installable": True,
}
45 changes: 45 additions & 0 deletions project_task_employee/demo/project_task.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>

<record id="restricted_project" model="project.project">
<field name="name">Project restricted</field>
<field name="employee_ids" eval="[(6, 0, [ref('hr.employee_jth'), ref('hr.employee_root')])]"/>
</record>

<record id="restricted_task_2" model="project.task">
<field name="name">2</field>
<field name="project_id" ref="restricted_project"/>
<field name="planned_hours">2</field>
<field name="date_deadline" eval="datetime.now()+timedelta(days=30)"/>
<field name="stage_id" ref="project.project_stage_0"/>
</record>

<record id="restricted_task_3" model="project.task">
<field name="name">3</field>
<field name="project_id" ref="restricted_project"/>
<field name="planned_hours">3</field>
<field name="date_deadline" eval="datetime.now()+timedelta(days=30)"/>
<field name="stage_id" ref="project.project_stage_0"/>
</record>

<record id="restricted_task_7" model="project.task">
<field name="name">7</field>
<field name="project_id" ref="restricted_project"/>
<field name="planned_hours">7</field>
<field name="date_deadline" eval="datetime.now()+timedelta(days=30)"/>
<field name="stage_id" ref="project.project_stage_0"/>
<field name="employee_category_id" ref="hr.employee_category_3"/>
</record>

<record id="restricted_task_1" model="project.task">
<field name="name">1</field>
<field name="project_id" ref="restricted_project"/>
<field name="planned_hours">1</field>
<field name="date_deadline" eval="datetime.now()+timedelta(days=30)"/>
<field name="stage_id" ref="project.project_stage_0"/>
<field name="employee_category_id" ref="hr.employee_category_5"/>
</record>

</odoo>
3 changes: 3 additions & 0 deletions project_task_employee/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import project
from . import project_task
12 changes: 12 additions & 0 deletions project_task_employee/models/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models


class ProjectProject(models.Model):
_inherit = 'project.project'

employee_ids = fields.Many2many(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comodel_name='hr.employee',
string="Employees",
)
62 changes: 62 additions & 0 deletions project_task_employee/models/project_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models


class Task(models.Model):
_inherit = 'project.task'

employee_domain_ids = fields.Many2many(
compute='_compute_employee_domain_ids',
comodel_name='hr.employee',
string="Employees",
)
employee_scheduling_ids = fields.Many2many(
compute='_compute_employee_scheduling_ids',
comodel_name='hr.employee',
string="Employees",
)
employee_id = fields.Many2one(
comodel_name='hr.employee',
string="Assigned to employee",
domain="[('id', 'in', employee_domain_ids)]",
help="If the task is not scheduled (without ending date), the "
"automated scheduling will only assign the task to the employee "
"selected here.",
)
employee_category_id = fields.Many2one(
comodel_name='hr.employee.category',
string="Employee category",
help="Only employee selected on the project belonging to the task "
"that have the categories selected here can do the task.",
)

@api.multi
@api.depends('project_id.employee_ids.category_ids',
'employee_category_id')
def _compute_employee_domain_ids(self):
for record in self:
emp = record.mapped('project_id.employee_ids')
task_skill = record.employee_category_id
if task_skill:
emp = emp.filtered(lambda r: task_skill in r.category_ids)
record.employee_domain_ids = emp.ids

@api.multi
@api.depends('date_end', 'employee_id', 'employee_domain_ids')
def _compute_employee_scheduling_ids(self):
for record in self:
employees = record.employee_id
if record.date_end or not record.employee_id:
employees = record.employee_domain_ids
record.employee_scheduling_ids = employees

@api.onchange('employee_domain_ids')
def _onchange_employee_domain_ids(self):
if self.employee_id not in self.employee_domain_ids:
self.employee_id = False

@api.onchange('employee_id')
def _onchange_employee_id(self):
if self.user_id != self.employee_id.user_id:
self.user_id = self.employee_id.user_id
3 changes: 3 additions & 0 deletions project_task_employee/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Tecnativa <https://www.tecnativa.com>`_:

* Ernesto Tejeda
3 changes: 3 additions & 0 deletions project_task_employee/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This module extends the functionality of project to allow you to add employees
to a project, to specify required skills (Employee category) to a task and to
add an employee to a task.
2 changes: 2 additions & 0 deletions project_task_employee/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_project_task
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add newline

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the comment line? Why?

41 changes: 41 additions & 0 deletions project_task_employee/tests/test_project_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline would be great



class TestProjectTask(TransactionCase):
def setUp(self):
super(TestProjectTask, self).setUp()
self.task_3 = self.env.ref("project_task_employee.restricted_task_3")
self.task_2 = self.env.ref("project_task_employee.restricted_task_2")
self.task_7 = self.env.ref("project_task_employee.restricted_task_7")
self.task_1 = self.env.ref("project_task_employee.restricted_task_1")

def test_employee_domain_ids(self):
jth = self.env.ref("hr.employee_jth")
root = self.env.ref("hr.employee_root")

self.assertEqual(self.task_3.employee_domain_ids, jth + root)
self.assertEqual(self.task_2.employee_domain_ids, jth + root)
self.assertEqual(self.task_7.employee_domain_ids, root)
self.assertEqual(self.task_1.employee_domain_ids, jth)

def test_change_employee_domain_ids_and_employee_id(self):
with self.env.do_in_onchange():

self.task_3.user_id = False
self.assertFalse(self.task_3.user_id)

self.task_3.employee_id = self.env.ref("hr.employee_root")
self.task_3._onchange_employee_id()
user = self.env.ref("base.user_root")
self.assertEqual(self.task_3.user_id, user)

category_5 = self.env.ref("hr.employee_category_5")
self.task_3.employee_category_id = category_5
self.task_3._onchange_employee_domain_ids()
self.assertFalse(self.task_3.employee_id)

self.assertEqual(self.task_3.user_id, user)
self.task_3._onchange_employee_id()
self.assertFalse(self.task_3.user_id)
24 changes: 24 additions & 0 deletions project_task_employee/views/project_task_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>

<record id="view_task_form2_inherit_schedule" model="ir.ui.view">
<field name="name">project.task.form.inherit.schedule</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_task_form2"/>
<field name="arch" type="xml">
<field name="user_id" position="attributes">
<attribute name="string">Assigned to user</attribute>
</field>
<field name="user_id" position="after">
<field name="employee_domain_ids" invisible="1"/>
<field name="employee_id"/>
</field>
<field name="tag_ids" position="after">
<field name="employee_category_id"/>
</field>
</field>
</record>

</odoo>
21 changes: 21 additions & 0 deletions project_task_employee/views/project_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Tecnativa - Ernesto Tejeda
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>

<record id="edit_project" model="ir.ui.view">
<field name="name">project.project.form.inherit.scheduling</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="project.edit_project"/>
<field name="arch" type="xml">
<notebook>
<page string="Employees">
<group>
<field name="employee_ids" nolabel="1"/>
</group>
</page>
</notebook>
</field>
</record>

</odoo>
1 change: 1 addition & 0 deletions project_task_scheduling/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**This file is going to be generated by oca-gen-addon-readme.**
3 changes: 3 additions & 0 deletions project_task_scheduling/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models
from . import wizards
27 changes: 27 additions & 0 deletions project_task_scheduling/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Automating Project Task Scheduling",
"version": "11.0.1.0.0",
"category": "Project Management",
"author": "Tecnativa, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/project",
"license": "AGPL-3",
"depends": [
"hr",
"hr_timesheet",
"project",
"project_task_employee",
"project_task_dependency",
"project_timeline",
"project_stage_closed",
],
"data": [
"views/project_task_scheduling_menu_views.xml",
"wizards/scheduling_wizard_views.xml",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ernestotejeda Add last

"views/project_task_scheduling_proposal_views.xml",
"views/project_task_scheduling_views.xml",
],
"installable": True,
}
3 changes: 3 additions & 0 deletions project_task_scheduling/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import project_task_scheduling
from . import project_task_scheduling_proposal
55 changes: 55 additions & 0 deletions project_task_scheduling/models/project_task_scheduling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models


class ProjectTaskScheduling(models.TransientModel):
_name = 'project.task.scheduling'
_description = 'Project task scheduling'
_rec_name = "task_id"

proposal_id = fields.Many2one(
comodel_name='project.task.scheduling.proposal',
string="Proposal",
ondelete='cascade',
required=True,
)
employee_id = fields.Many2one(
comodel_name='hr.employee',
string="Employee",
required=True,
)
task_id = fields.Many2one(
comodel_name='project.task',
string="Task",
required=True,
)
datetime_start = fields.Datetime(
required=True,
)
datetime_stop = fields.Datetime(
required=True,
)
delayed = fields.Boolean(
compute='_compute_delayed',
default=False,
)

@api.multi
@api.depends('task_id.date_deadline', 'datetime_stop')
def _compute_delayed(self):
for rec in self:
date_deadline = fields.Date.from_string(rec.task_id.date_deadline)
datetime_stop = fields.Datetime.from_string(rec.datetime_stop)
if date_deadline and datetime_stop:
rec.delayed = date_deadline < datetime_stop.date()

@api.multi
def set_assignation(self):
for record in self:
record.task_id.write({
'employee_id': record.employee_id.id,
'user_id': record.employee_id.user_id.id,
'date_start': record.datetime_start,
'date_end': record.datetime_stop,
})
Loading