diff --git a/addons/account/project/project_view.xml b/addons/account/project/project_view.xml
index 789c76addcf..77e03c23700 100644
--- a/addons/account/project/project_view.xml
+++ b/addons/account/project/project_view.xml
@@ -243,7 +243,7 @@
- Analytic Entries
+ Analytic Items
account.analytic.line
form
tree,form
diff --git a/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py b/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py
index 0ab5d08a6ec..0b4568fe8f4 100644
--- a/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py
+++ b/addons/outlook/plugin/openerp-outlook-plugin/tiny_xmlrpc.py
@@ -288,6 +288,7 @@ class XMLRpcConn(object):
headers[line[:split_here]] = line[split_here:]
temp1 = headers.get('Message-ID')
temp2 = headers.get('Message-Id')
+ referances = headers.get('References')
if temp1 == None: message_id = temp2
if temp2 == None: message_id = temp1
startCut = message_id.find("<")
diff --git a/addons/project/project.py b/addons/project/project.py
index dda6819839a..b6664f9869b 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -126,9 +126,11 @@ class project(osv.osv):
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the project without removing it."),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of Projects."),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc.", ondelete="cascade", required=True),
- 'priority': fields.integer('Sequence', help="Gives the sequence order when displaying a list of task"),
+ 'priority': fields.integer('Sequence', help="Gives the sequence order when displaying the list of projects"),
'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+
+ 'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose, but a user has to be member of a project to add a the to this project.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'parent_id': fields.many2one('project.project', 'Parent Project'),
'tasks': fields.one2many('project.task', 'project_id', "Project tasks"),
'planned_hours': fields.function(_progress_rate, multi="progress", method=True, string='Planned Time', help="Sum of planned hours of all tasks related to this project and its child projects.",
store = {
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 9539bd9acad..6ec47903ad2 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -29,20 +29,17 @@
-
-
-
-
-
-
+
+
+
@@ -226,7 +223,7 @@
-
+
-
+
diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml
index ff4cfd8575b..8203cbfdf06 100644
--- a/addons/project_long_term/project_long_term_view.xml
+++ b/addons/project_long_term/project_long_term_view.xml
@@ -116,10 +116,10 @@
-
+
-
+
@@ -228,6 +228,7 @@
+
@@ -322,7 +323,7 @@
form
-
+
diff --git a/addons/project_long_term/test/phase_constraint.yml b/addons/project_long_term/test/phase_constraint.yml
new file mode 100644
index 00000000000..cf6bfa844a6
--- /dev/null
+++ b/addons/project_long_term/test/phase_constraint.yml
@@ -0,0 +1,179 @@
+-
+ I have a project 'Develop yaml Project Module'.
+-
+ !record {model: project.project, id: project_project_developyamlproject0}:
+ name: "Develop Yaml Project Module"
+ date_start: !eval time.strftime('%Y-%m-%d')
+-
+ I have set Working Time from Monday to Friday from 9am to 17pm.
+-
+ !record {model: resource.calendar, id: resource_calendar_hoursweeks0}:
+ name: "from Monday to Friday, from 9am to 17pm"
+
+-
+ I have set Day1 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day1"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "0"
+ calendar_id : resource_calendar_hoursweeks0
+
+-
+ I have set Day2 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day2"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "1"
+ calendar_id : resource_calendar_hoursweeks0
+
+-
+ I have set Day3 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day3"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "2"
+ calendar_id : resource_calendar_hoursweeks0
+
+-
+ I have set Day4 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day4"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "3"
+ calendar_id : resource_calendar_hoursweeks0
+
+-
+ I have set Day5 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day5"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "4"
+ calendar_id : resource_calendar_hoursweeks0
+
+
+-
+ Now Set working period to Project 'Develop yaml Project Module'
+-
+ !python {model: project.project}: |
+ self.write(cr, uid, [ref("project_project_developyamlproject0")], {'resource_calendar_id': ref("resource_calendar_hoursweeks0")})
+
+
+-
+ Creating 3 consecutive 5-days phases.
+ For that Creating a Analyst Human resource to analyst Project Yaml.
+-
+ !record {model: resource.resource, id: resource_resource_analyst1}:
+ calendar_id: project_long_term.resource_calendar_hoursweeks0
+ name: Analyst
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: base.user_admin
+
+-
+ Creating Developer Human resource who develop Yaml
+-
+ !record {model: resource.resource, id: resource_resource_develop0}:
+ calendar_id: project_long_term.resource_calendar_hoursweeks0
+ name: Developer
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: base.user_admin
+-
+ Creating a Tester Human resource for testing Yaml
+-
+ !record {model: resource.resource, id: resource_resource_tester1}:
+ calendar_id: project_long_term.resource_calendar_hoursweeks0
+ name: tester
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: base.user_admin
+
+-
+ Create 3 a project phase and NO one depends on other one.
+ so,they should start on the same day.
+ Creating First 'Analysis Flow for Yaml' Project Phase.
+-
+ !record {model: project.phase, id: project_phase_analysisflowforyaml0}:
+ date_start: !eval time.strftime('%Y-%m-%d')
+ duration: 6.0
+ name: "Analysis Flow for Yaml"
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ responsible_id: project.res_users_analyst
+ state: draft
+
+-
+ I update the Constrain Date Start adn Date End for phase Analysis Flow for Yaml
+-
+ !python {model : project.phase }: |
+ import datetime
+ from dateutil.relativedelta import *
+ start = datetime.date.today() - relativedelta(days=2)
+ end = datetime.date.today() + relativedelta(days=6)
+ self.write(cr,uid, [(ref("project_phase_analysisflowforyaml0"))], {'constraint_date_start': start, 'constraint_date_end':end})
+
+-
+ Create project phase 'Develop yaml' with constraint date.
+-
+ !record {model: project.phase, id: project_phase_developyaml0}:
+ duration: 6.0
+ name: Develop Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ previous_phase_ids:
+ - project_phase_analysisflowforyaml0
+
+-
+ I update the Constrain Date Start adn Date End for phase Develop yaml
+-
+ !python {model : project.phase }: |
+ import datetime
+ from dateutil.relativedelta import *
+ start = datetime.date.today() - relativedelta(days=5)
+ end = datetime.date.today() + relativedelta(days=10)
+ self.write(cr,uid, [(ref("project_phase_developyaml0"))], {'constraint_date_start': start, 'constraint_date_end':end})
+-
+ Create project phase 'Test Yaml'
+-
+ !record {model: project.phase, id: project_phase_testyaml0}:
+ duration: 6.0
+ name: Testing Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ previous_phase_ids:
+ - project_phase_developyaml0
+ constraint_date_start :
+ constraint_date_end :
+-
+ Compute Schedule of phases For One project
+-
+ !record {model: project.compute.phases, id: project_compute_phases_0}:
+ project_id: project_project_developyamlproject0
+ target_project: one
+
+-
+ Schedule project phases using "Compute Phase Scheduling"
+-
+ !python {model: project.project}: |
+ self.schedule_phases(cr, uid, [ref("project_project_developyamlproject0")])
+
+-
+ After scheduling,check that
+ Phase "Analysis Flow for Yaml" and "Test Yaml" Phase should start on the project start date while "Develop yaml" Phase should respect the constraint.
+-
+ !python {model: project.project}: |
+ proj=self.browse(cr, uid, [ref("project_project_developyamlproject0")])[0]
+ for phase in proj.phase_ids:
+ for phase1 in proj.phase_ids:
+ if phase1.id != phase.id and phase.constraint_date_start == phase1.date_start:
+ raise AssertionError("Phases not scheduled")
diff --git a/addons/project_long_term/test/project_schedule_consecutive_day.yml b/addons/project_long_term/test/project_schedule_consecutive_day.yml
new file mode 100644
index 00000000000..9f4e1231d11
--- /dev/null
+++ b/addons/project_long_term/test/project_schedule_consecutive_day.yml
@@ -0,0 +1,126 @@
+-
+ Create a project 'Develop yaml Project Module'.
+-
+ !record {model: project.project, id: project_project_developyamlproject123}:
+ name: "Develop Yaml Project Module"
+ date_start: !eval time.strftime('%Y-%m-%d')
+
+-
+ I have set Working Time from Monday to Friday from 9am to 17pm.
+-
+ !record {model: resource.calendar, id: resource_calendar_hoursweekstest2}:
+ name: "from Monday to Friday, from 9am to 17pm"
+
+-
+ I have set Day1 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday1}:
+ name: "Day1"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "0"
+ calendar_id : resource_calendar_hoursweekstest2
+
+-
+ I have set Day2 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday2}:
+ name: "Day2"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "1"
+ calendar_id : resource_calendar_hoursweekstest2
+
+-
+ I have set Day3 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday3}:
+ name: "Day3"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "2"
+ calendar_id : resource_calendar_hoursweekstest2
+
+-
+ I have set Day4 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday4}:
+ name: "Day4"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "3"
+ calendar_id : resource_calendar_hoursweekstest2
+
+-
+ I have set Day5 Working Time for Monday to Friday from 9am to 17pm working hour
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_atendanceday5}:
+ name: "Day5"
+ hour_from : 09.00
+ hour_to : 17.00
+ dayofweek : "4"
+ calendar_id : resource_calendar_hoursweekstest2
+
+-
+ Now Set working period to Project 'Develop yaml Project Module'
+-
+ !python {model: project.project}: |
+ self.write(cr, uid, [ref("project_project_developyamlproject123")], {'resource_calendar_id': ref("resource_calendar_hoursweekstest2")})
+
+-
+ Create 3 a project phase.
+ First 'Analysis Flow for Yaml'Project Phase
+-
+ !record {model: project.phase, id: project_phase_analysisflowforyaml0}:
+ date_start: !eval time.strftime('%Y-%m-%d')
+ duration: 5.0
+ name: "Analysis Flow for Yaml"
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject123
+ state: draft
+
+-
+ Create project phase 'Develop yaml'
+-
+ !record {model: project.phase, id: project_phase_establishingprojectfeasibility0}:
+ duration: 5.0
+ name: Develop Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject123
+ previous_phase_ids:
+ - project_phase_analysisflowforyaml0
+
+-
+ Create project phase 'Test Yaml'
+-
+ !record {model: project.phase, id: project_phase_preparationofengineeringdesigns0}:
+ duration: 5.0
+ name: Testing Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject123
+ previous_phase_ids:
+ - project_phase_establishingprojectfeasibility0
+
+-
+ Compute Schedule of phases For One project
+-
+ !record {model: project.compute.phases, id: project_compute_phases_0}:
+ project_id: project_project_developyamlproject123
+ target_project: one
+
+-
+ Schedule project phases using Compute Phase Scheduling
+-
+ !python {model: project.project}: |
+ self.schedule_phases(cr, uid, [ref("project_project_developyamlproject123")])
+
+-
+ After scheduling, Check that phases scheduled, check that either of phase's start_date, end_date not null.
+-
+ !python {model: project.project}: |
+ proj=self.browse(cr, uid, [ref("project_project_developyamlproject123")])[0]
+ for phase in proj.phase_ids:
+ if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
+ raise AssertionError("Phases not scheduled")
+
+
diff --git a/addons/project_long_term/test/project_schedule_without_wroking_hour.yml b/addons/project_long_term/test/project_schedule_without_wroking_hour.yml
new file mode 100644
index 00000000000..0c810227717
--- /dev/null
+++ b/addons/project_long_term/test/project_schedule_without_wroking_hour.yml
@@ -0,0 +1,77 @@
+-
+ Create a project 'Develop yaml Implementation Module'.
+-
+ !record {model: project.project, id: project_project_developyamlproject0}:
+ name: "Develop Yaml Project Module"
+ date_start: !eval time.strftime('%Y-%m-%d')
+
+-
+ Create 4 Project phase.
+ First Project Phase 'Analysis Flow for Yaml'
+-
+ !record {model: project.phase, id: project_phase_analysisflowforyaml0}:
+ date_start: !eval time.strftime('%Y-%m-%d')
+ duration: 6.0
+ product_uom: product.uom_day
+ name: "Analysis Flow for Yaml"
+ project_id: project_project_developyamlproject0
+ responsible_id: project.res_users_analyst
+ state: draft
+
+-
+ Create project phase 'Develop yaml'
+-
+ !record {model: project.phase, id: project_phase_establishingprojectfeasibility0}:
+ duration: 6.0
+ name: "Develop yaml"
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ previous_phase_ids:
+ - project_phase_analysisflowforyaml0
+ state: draft
+-
+ Create project phase 'Test Yaml'
+-
+ !record {model: project.phase, id: project_phase_preparationofengineeringdesigns0}:
+ duration: 6.0
+ name: Testing Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ previous_phase_ids:
+ - project_phase_establishingprojectfeasibility0
+ state: draft
+
+-
+ Create project phase 'Implement Yaml'
+-
+ !record {model: project.phase, id: project_phase_implementingreadycase0}:
+ duration: 6.0
+ name: Testing Yaml
+ product_uom: product.uom_day
+ project_id: project_project_developyamlproject0
+ previous_phase_ids:
+ - project_phase_preparationofengineeringdesigns0
+ state: draft
+-
+ Compute Schedule of phases For One project
+-
+ !record {model: project.compute.phases, id: project_compute_phases_0}:
+ project_id: project_project_developyamlproject0
+ target_project: one
+
+-
+ Schedule project phases using Compute Phase Scheduling
+-
+ !python {model: project.project}: |
+ self.schedule_phases(cr, uid, [ref("project_project_developyamlproject0")])
+
+-
+ After scheduling, Check that phases scheduled, check that either of phase's start_date, end_date not null.
+-
+ !python {model: project.project}: |
+ proj=self.browse(cr, uid, [ref("project_project_developyamlproject0")])[0]
+ for phase in proj.phase_ids:
+ if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
+ raise AssertionError("Phases not scheduled")
+
+
diff --git a/addons/project_long_term/test/schedule_phase_tasks.yml b/addons/project_long_term/test/schedule_phase_tasks.yml
index aa54fa1ac57..1526d04f933 100644
--- a/addons/project_long_term/test/schedule_phase_tasks.yml
+++ b/addons/project_long_term/test/schedule_phase_tasks.yml
@@ -23,12 +23,8 @@
state: draft
resource_ids:
- resource_id: project_long_term.resource_analyst
- useability: 80.0
- resource_id: project_long_term.resource_developer
- useability: 30.0
- resource_id: project_long_term.resource_designer
- useability: 30.0
-
-
Create the phase task 'Develop GUI for Server Configuration'
diff --git a/addons/project_long_term/test/schedule_project_phases.yml b/addons/project_long_term/test/schedule_project_phases.yml
index e06feaaa4ca..829258eefc8 100644
--- a/addons/project_long_term/test/schedule_project_phases.yml
+++ b/addons/project_long_term/test/schedule_project_phases.yml
@@ -4,7 +4,14 @@
!record {model: project.project, id: project_project_worldbanksproject0}:
name: "World Bank's Project"
priority: 4
-
+ members:
+ - project.res_users_analyst
+ - project.res_users_project_manager
+ - project.res_users_technical_leader
+ - project.res_users_developer
+ - project.res_users_designer
+ - project.res_users_tester
+
-
Create a project phase 'Defining Client's Basic Idea of Project'
-
@@ -14,8 +21,7 @@
name: "Defining Client's Basic Idea of Project"
product_uom: product.uom_day
project_id: project_project_worldbanksproject0
-
-
+
-
Create project phase 'Establishing Project Feasibility'
-
@@ -25,7 +31,49 @@
name: Establishing Project Feasibility
product_uom: product.uom_day
project_id: project_project_worldbanksproject0
+
+-
+ Resource1
+-
+ !record {model: project.resource.allocation, id: res_phase1}:
+ resource_id: project_long_term.resource_project_manager
+ phase_id: project_phase_definingclientsbasicideaofproject0
+-
+ Resource2
+-
+ !record {model: project.resource.allocation, id: res_phase2}:
+ resource_id: project_long_term.resource_analyst
+ phase_id: project_phase_definingclientsbasicideaofproject0
+
+-
+ Resource3
+-
+ !record {model: project.resource.allocation, id: res_phase3}:
+ resource_id: project_long_term.resource_technical_leader
+ phase_id: project_phase_definingclientsbasicideaofproject0
+
+-
+ Create the phase task 'Develop GUI for Server Configuration'
+-
+ !record {model: project.task, id: project_task_t0}:
+ name: Develop GUI for Server Configuration
+ planned_hours: 20.0
+ state: draft
+ phase_id: project_phase_definingclientsbasicideaofproject0
+ project_id: project_project_worldbanksproject0
+
+-
+ Create the phase task 'Develop GUI for Modules Configuration'
+-
+ !record {model: project.task, id: project_task_t1}:
+ name: Develop GUI for Modules Configuration
+ planned_hours: 25.0
+ remaining_hours: 25.0
+ state: draft
+ phase_id: project_phase_definingclientsbasicideaofproject0
+ project_id: project_project_worldbanksproject0
+
-
Create project phase 'Preparation of Engineering Designs'
-
@@ -36,7 +84,43 @@
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
-
+-
+ Resource4
+-
+ !record {model: project.resource.allocation, id: res_phase4}:
+ resource_id: project_long_term.resource_developer
+ phase_id: project_phase_preparationofengineeringdesigns0
+
+-
+ Resource5
+-
+ !record {model: project.resource.allocation, id: res_phase5}:
+ resource_id: project_long_term.resource_designer
+ phase_id: project_phase_preparationofengineeringdesigns0
+
+-
+ Create the phase task 'Develop GUI for Client Configuration'
+-
+ !record {model: project.task, id: project_task_t2}:
+ name: Develop GUI for Server Configuration
+ planned_hours: 20.0
+ remaining_hours: 20.0
+ state: draft
+ phase_id: project_phase_preparationofengineeringdesigns0
+ project_id: project_project_worldbanksproject0
+
+-
+ Create the phase task 'Develop GUI for Client Module Configuration'
+-
+ !record {model: project.task, id: project_task_t3}:
+ name: Develop GUI for Modules Configuration
+ planned_hours: 25.0
+ remaining_hours: 25.0
+ state: draft
+ phase_id: project_phase_preparationofengineeringdesigns0
+ project_id: project_project_worldbanksproject0
+
+
-
Create project phase 'Procurement of Works and Goods'
-
@@ -46,14 +130,13 @@
name: Procurement of Works and Goods
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
-
-
+
-
Create project phase 'Project Construction'
-
!record {model: project.phase, id: project_phase_projectconstruction0}:
date_start: '2010-06-02'
- duration: 4320.0
+ duration: 20.0
name: Project Construction
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
diff --git a/addons/project_long_term/test/test_schedule_phases_case1.yml b/addons/project_long_term/test/test_schedule_phases_case1.yml
new file mode 100644
index 00000000000..214512b923f
--- /dev/null
+++ b/addons/project_long_term/test/test_schedule_phases_case1.yml
@@ -0,0 +1,65 @@
+-
+ In order to test scheduling of project phases, I create two different phases and
+ test it with two different dates for scheduling.
+-
+ I create a project 'Development and Testing'.
+-
+ !record {model: project.project, id: project_project_project0}:
+ date_start: '2010-12-30'
+ balance: 0.0
+ credit: 0.0
+ currency_id: base.EUR
+ debit: 0.0
+ effective_hours: 0.0
+ members:
+ - base.user_admin
+ name: Development and Testing
+ planned_hours: 0.0
+ progress_rate: 0.0
+ quantity: 0.0
+ quantity_max: 0.0
+ state: open
+ type_ids:
+ - project.project_tt_specification
+ - project.project_tt_development
+ - project.project_tt_testing
+ - project.project_tt_merge
+-
+ I create first phase of the project.
+-
+ !record {model: project.phase, id: project_phase_firstphase0}:
+ duration: 2.0
+ name: First Phase
+ product_uom: product.uom_day
+ project_id: project_project_project0
+ state: draft
+-
+ I create second phase of the project.
+-
+ !record {model: project.phase, id: project_phase_secondphase0}:
+ duration: 3.0
+ name: Second Phase
+ previous_phase_ids:
+ - project_phase_firstphase0
+ product_uom: product.uom_day
+ project_id: project_project_project0
+ state: draft
+-
+ Now I create a record to compute the phase of project.
+-
+ !record {model: project.compute.phases, id: project_compute_phases0}:
+ target_project: 'one'
+ project_id: project_project_project0
+-
+ I schedule the phases.
+-
+ !python {model: project.compute.phases}: |
+ self.check_selection(cr, uid, [ref("project_compute_phases0")])
+-
+ I check the starting and ending dates of both phases.
+-
+ !python {model: project.phase}: |
+ first_phase = self.browse(cr, uid, ref('project_phase_firstphase0'))
+ assert (first_phase.date_start == '2010-12-30' and first_phase.date_end == '2010-12-31'),'Dates are wrong!'
+ second_phase = self.browse(cr, uid, ref('project_phase_secondphase0'))
+ assert (second_phase.date_start == '2011-01-01' and second_phase.date_end == '2011-01-03'),'Dates are wrong!'
diff --git a/addons/project_long_term/test/test_schedule_phases_case2.yml b/addons/project_long_term/test/test_schedule_phases_case2.yml
new file mode 100644
index 00000000000..67a7332cf5b
--- /dev/null
+++ b/addons/project_long_term/test/test_schedule_phases_case2.yml
@@ -0,0 +1,193 @@
+-
+ In order to test scheduling of project phases, I create two different
+ working periods and resources. And schedule the phases.
+-
+ I create first working period 'Working Time A'.
+-
+ !record {model: resource.calendar, id: resource_calendar_workingtimea0}:
+ attendance_ids:
+ - dayofweek: '0'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Monday
+ - dayofweek: '1'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Tuesday
+ - dayofweek: '2'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Wednesday
+ - dayofweek: '3'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Thursday
+ name: Working Time A
+
+-
+ Creating a resource.calendar.attendance record
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_attendance_monday0}:
+ calendar_id: resource_calendar_workingtimea0
+ dayofweek: '0'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Monday
+-
+ Creating a resource.calendar.attendance record
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_attendance_tuesday0}:
+ calendar_id: resource_calendar_workingtimea0
+ dayofweek: '1'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Tuesday
+-
+ Creating a resource.calendar.attendance record
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_attendance_wednesday0}:
+ calendar_id: resource_calendar_workingtimea0
+ dayofweek: '2'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Wednesday
+-
+ Creating a resource.calendar.attendance record
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_attendance_thursday0}:
+ calendar_id: resource_calendar_workingtimea0
+ dayofweek: '3'
+ hour_from: 10.0
+ hour_to: 16.0
+ name: Thursday
+-
+ I create second working period 'Working Time B'.
+-
+ !record {model: resource.calendar, id: resource_calendar_workingtimeb0}:
+ attendance_ids:
+ - dayofweek: '4'
+ hour_from: 9.0
+ hour_to: 18.0
+ name: Friday
+ name: Working Time B
+-
+ Creating a resource.calendar.attendance record
+-
+ !record {model: resource.calendar.attendance, id: resource_calendar_attendance_friday0}:
+ calendar_id: resource_calendar_workingtimeb0
+ dayofweek: '4'
+ hour_from: 9.0
+ hour_to: 18.0
+ name: Friday
+-
+ I create first resource say 'Resource X' without assigning working period.
+-
+ !record {model: resource.resource, id: resource_resource_resourcex0}:
+ name: Resource X
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: base.user_admin
+-
+ I create first resource say 'Resource Y' with working period 'Working Time B'.
+-
+ !record {model: resource.resource, id: resource_resource_resourcey0}:
+ calendar_id: resource_calendar_workingtimeb0
+ name: Resource Y
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: base.user_admin
+-
+ I create a project 'Development and Testing' and assign working period 'Working Time A'.
+-
+ !record {model: project.project, id: project_project_project0}:
+ balance: 0.0
+ credit: 0.0
+ currency_id: base.EUR
+ debit: 0.0
+ effective_hours: 0.0
+ members:
+ - base.user_admin
+ name: Development and Testing
+ planned_hours: 20.0
+ progress_rate: 0.0
+ quantity: 0.0
+ quantity_max: 0.0
+ resource_calendar_id: resource_calendar_workingtimea0
+ state: open
+ tasks:
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task 1
+ planned_hours: 10.0
+ remaining_hours: 10.0
+ state: draft
+ total_hours: 10.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task 2
+ planned_hours: 10.0
+ remaining_hours: 10.0
+ state: draft
+ total_hours: 10.0
+ total_hours: 10.0
+ members:
+ - project.res_users_analyst
+ - project.res_users_project_manager
+ - project.res_users_technical_leader
+ - project.res_users_developer
+ - project.res_users_designer
+ - project.res_users_tester
+ type_ids:
+ - project.project_tt_specification
+ - project.project_tt_development
+ - project.project_tt_testing
+ - project.project_tt_merge
+
+-
+ I create a phase 'Initial Phase' for project 'Development and Testing'.
+-
+ !record {model: project.phase, id: project_phase_phase0}:
+ date_start: '2011-01-03'
+ duration: 0.0
+ name: Initial Phase
+ product_uom: product.uom_day
+ project_id: project_project_project0
+ state: draft
+-
+ I create first task 'Developing module' and assign 10h.
+-
+ !record {model: project.task, id: project_task_task0}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Developing module
+ planned_hours: 10.0
+ project_id: project_project_project0
+ remaining_hours: 10.0
+ state: draft
+ total_hours: 10.0
+ phase_id: project_phase_phase0
+-
+ I create first task 'Testing module' and assign 10h.
+-
+ !record {model: project.task, id: project_task_task1}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Testing module
+ planned_hours: 10.0
+ project_id: project_project_project0
+ remaining_hours: 10.0
+ state: draft
+ total_hours: 10.0
+ phase_id: project_phase_phase0
+-
+ Now I create a record to compute the phase of project.
+-
+ !record {model: project.compute.phases, id: project_compute_phases0}:
+ target_project: 'one'
+ project_id: project_project_project0
+-
+ I schedule the phases.
+-
+ !python {model: project.compute.phases}: |
+ self.check_selection(cr, uid, [ref("project_compute_phases0")])
+
diff --git a/addons/project_long_term/test/test_schedule_tasks_case1.yml b/addons/project_long_term/test/test_schedule_tasks_case1.yml
new file mode 100644
index 00000000000..78bf5e318a4
--- /dev/null
+++ b/addons/project_long_term/test/test_schedule_tasks_case1.yml
@@ -0,0 +1,263 @@
+-
+ In order to test scheduling of tasks, I create four tasks with different sequences and schedule them.
+-
+ I create address for first user.
+-
+ !record {model: res.partner.address, id: res_partner_address_user0}:
+ name: User 1
+-
+ I create address for second user.
+-
+ !record {model: res.partner.address, id: res_partner_address_user1}:
+ name: User 2
+-
+ I create first user.
+-
+ !record {model: res.users, id: res_users_user0}:
+ address_id: res_partner_address_user0
+ company_id: base.main_company
+ context_lang: en_US
+ groups_id:
+ - base.group_partner_manager
+ - base.group_user
+ login: user1
+ name: User 1
+ password: user1
+-
+ I create second user.
+-
+ !record {model: res.users, id: res_users_user1}:
+ address_id: res_partner_address_user1
+ company_id: base.main_company
+ context_lang: en_US
+ groups_id:
+ - base.group_partner_manager
+ - base.group_user
+ login: user2
+ name: User 2
+ password: user2
+-
+ I create a Project.
+-
+ !record {model: project.project, id: project_project_projecta0}:
+ balance: 0.0
+ credit: 0.0
+ currency_id: base.EUR
+ debit: 0.0
+ effective_hours: 0.0
+ name: Project A
+ members:
+ - res_users_user0
+ - res_users_user1
+ phase_ids:
+ - date_start: '2011-01-06'
+ duration: 2.0
+ name: Phase A
+ product_uom: product.uom_day
+ state: draft
+ task_ids:
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task D
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task C
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 11
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task B
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 13
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task A
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 14
+ state: draft
+ total_hours: 5.0
+ planned_hours: 20.0
+ progress_rate: 0.0
+ quantity: 0.0
+ quantity_max: 0.0
+ state: open
+ tasks:
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task D
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task C
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 11
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task B
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 13
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task A
+ planned_hours: 5.0
+ remaining_hours: 5.0
+ sequence: 14
+ state: draft
+ total_hours: 5.0
+ total_hours: 15.0
+-
+ I create first task with highest sequence.
+-
+ !record {model: project.task, id: project_task_taska0}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task A
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 14
+ state: draft
+ total_hours: 5.0
+-
+ I create second task.
+-
+ !record {model: project.task, id: project_task_taskb0}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task B
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 13
+ state: draft
+ total_hours: 5.0
+-
+ I create third task.
+-
+ !record {model: project.task, id: project_task_taskc0}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task C
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 11
+ state: draft
+ total_hours: 5.0
+-
+ I create fourth task with lowest sequence.
+-
+ !record {model: project.task, id: project_task_taskd0}:
+ delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task D
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ state: draft
+ total_hours: 5.0
+-
+ Now I create a resource for first user.
+-
+ !record {model: resource.resource, id: resource_resource_user0}:
+ name: User 1
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: res_users_user0
+-
+ I create a resource for second user.
+-
+ !record {model: resource.resource, id: resource_resource_user1}:
+ name: User 2
+ resource_type: user
+ time_efficiency: 1.0
+ user_id: res_users_user1
+-
+ Now I create one phase for the project.
+-
+ !record {model: project.phase, id: project_phase_phasea0}:
+ date_start: '2011-01-06'
+ duration: 2.0
+ name: Phase A
+ product_uom: product.uom_day
+ project_id: project_project_projecta0
+ resource_ids:
+ - project_id: project_project_projecta0
+ resource_id: resource_resource_user0
+ - project_id: project_project_projecta0
+ resource_id: resource_resource_user1
+ state: draft
+ task_ids:
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task D
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task C
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 11
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task B
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 13
+ state: draft
+ total_hours: 5.0
+ - delay_hours: 0.0
+ effective_hours: 0.0
+ name: Task A
+ planned_hours: 5.0
+ project_id: project_project_projecta0
+ remaining_hours: 5.0
+ sequence: 14
+ state: draft
+ total_hours: 5.0
+-
+ Now I create a record to schedule the tasks of project.
+-
+ !record {model: project.compute.tasks, id: project_compute_tasks0}:
+ project_id: project_project_projecta0
+-
+ I schedule the tasks.
+-
+ !python {model: project.compute.tasks}: |
+ self.compute_date(cr, uid, [ref("project_compute_tasks0")])
+-
+ I check that whether the tasks now allocated to respected resources or not.
+-
+ !python {model: project.task}: |
+ task_ids = self.search(cr, uid, [('project_id','=',ref('project_project_projecta0'))])
+ for task in self.browse(cr, uid, task_ids):
+ if (not task.user_id) or (not task.date_start) or (not task.date_end):
+ raise AssertionError("Tasks are not scheduled.")
diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py
index b6ec7d069bd..141b5756271 100644
--- a/addons/project_timesheet/project_timesheet.py
+++ b/addons/project_timesheet/project_timesheet.py
@@ -28,16 +28,7 @@ from tools.translate import _
class project_project(osv.osv):
_inherit = 'project.project'
- def onchange_partner_id(self, cr, uid, ids, part=False, context=None):
- result = super(project_project, self).onchange_partner_id(cr, uid, ids, part, context=context)
- if result.get('value', False):
- try:
- d = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'hr_timesheet_invoice', 'timesheet_invoice_factor1')
- if d:
- result['value']['to_invoice'] = d[1]
- except ValueError, e:
- pass
- return result
+
project_project()
class project_work(osv.osv):
@@ -231,4 +222,16 @@ class res_partner(osv.osv):
context=context)
res_partner()
+class account_analytic_line(osv.osv):
+ _inherit = "account.analytic.line"
+ def on_change_account_id(self, cr, uid, ids, account_id):
+ res = {}
+ if not account_id:
+ return res
+ res.setdefault('value',{})
+ acc = self.pool.get('account.analytic.account').browse(cr, uid, account_id)
+ st = acc.to_invoice.id
+ res['value']['to_invoice'] = st or False
+ return res
+account_analytic_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_timesheet/project_timesheet_view.xml b/addons/project_timesheet/project_timesheet_view.xml
index 7d55ca419be..56dfa068b21 100644
--- a/addons/project_timesheet/project_timesheet_view.xml
+++ b/addons/project_timesheet/project_timesheet_view.xml
@@ -11,7 +11,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
diff --git a/addons/resource/resource.py b/addons/resource/resource.py
index 30def0c2e16..9e3eb62f0ba 100644
--- a/addons/resource/resource.py
+++ b/addons/resource/resource.py
@@ -250,7 +250,7 @@ class resource_resource(osv.osv):
"""
Return a list of Resource Class objects for the resources allocated to the phase.
"""
- resource_objs = []
+ resource_objs = {}
user_pool = self.pool.get('res.users')
for user in user_pool.browse(cr, uid, user_ids, context=context):
resource_ids = self.search(cr, uid, [('user_id', '=', user.id)], context=context)
@@ -264,12 +264,18 @@ class resource_resource(osv.osv):
resource_cal = resource.calendar_id.id
if resource_cal:
leaves = self.compute_vacation(cr, uid, calendar_id, resource.id, resource_cal, context=context)
- resource_objs.append(classobj(str(user.name), (Resource,),{
- '__doc__': user.name,
- '__name__': user.name,
- 'vacation': tuple(leaves),
- 'efficiency': resource_eff,
- }))
+ temp = {
+ 'name' : resource.name,
+ 'vacation': tuple(leaves),
+ 'efficiency': resource_eff,
+ }
+ resource_objs[resource_id] = temp
+# resource_objs.append(classobj(str(user.name), (Resource,),{
+# '__doc__': user.name,
+# '__name__': user.name,
+# 'vacation': tuple(leaves),
+# 'efficiency': resource_eff,
+# }))
return resource_objs
def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
@@ -322,6 +328,7 @@ class resource_resource(osv.osv):
# and create a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
for week in weeks:
res_str = ""
+ day = None
if week_days.has_key(week['dayofweek']):
day = week_days[week['dayofweek']]
wk_days[week['dayofweek']] = week_days[week['dayofweek']]
@@ -348,6 +355,13 @@ class resource_resource(osv.osv):
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
+ #TODO: Write optimized alogrothem for resource availability. : Method Yet not implemented
+ def check_availability(self, cr, uid, ids, start, end, context=None):
+ if context == None:
+ contex = {}
+ allocation = {}
+ return allocation
+
resource_resource()
class resource_calendar_leaves(osv.osv):
diff --git a/addons/resource/resource_view.xml b/addons/resource/resource_view.xml
index 424955d0584..7663a5af5d4 100644
--- a/addons/resource/resource_view.xml
+++ b/addons/resource/resource_view.xml
@@ -225,7 +225,7 @@
-
+