Merge lp:~openerp-dev/openobject-addons/trunk-bug-713367-jam into lp:openobject-addons

Proposed by Jigar A.
Status: Merged
Approved by: tfr (Openerp)
Approved revision: no longer in the source branch.
Merged at revision: 4474
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-bug-713367-jam
Merge into: lp:openobject-addons
Diff against target: 169 lines (+68/-26)
1 file modified
project/project.py (+68/-26)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-bug-713367-jam
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+52011@code.launchpad.net

Description of the change

Hello,
  Changes with Merge Proposal :
    + Bug lp:713367: Project Template Duplication Error Remove
    + Project Task : Check Recursion Algorithm Re Worked By TFR
  Kindly Review this.
Thank You

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'project/project.py'
2--- project/project.py 2011-02-21 14:05:10 +0000
3+++ project/project.py 2011-03-03 07:01:33 +0000
4@@ -205,20 +205,37 @@
5 if context is None:
6 context = {}
7
8- proj = self.browse(cr, uid, id, context=context)
9 default = default or {}
10 context['active_test'] = False
11 default['state'] = 'open'
12 if not default.get('name', False):
13 default['name'] = proj.name + _(' (copy)')
14+
15 res = super(project, self).copy(cr, uid, id, default, context)
16+ return res
17+
18+
19+ def template_copy(self, cr, uid, id, default={}, context=None):
20+ task_obj = self.pool.get('project.task')
21+ proj = self.browse(cr, uid, id, context=context)
22+
23+ default['tasks'] = [] #avoid to copy all the task automaticly
24+ res = self.copy(cr, uid, id, default=default, context=context)
25+
26+ #copy all the task manually
27+ map_task_id = {}
28+ for task in proj.tasks:
29+ map_task_id[task.id] = task_obj.copy(cr, uid, task.id, {}, context=context)
30+
31+ self.write(cr, uid, res, {'tasks':[(6,0, map_task_id.values())]})
32+ task_obj.duplicate_task(cr, uid, map_task_id, context=context)
33
34 return res
35
36 def duplicate_template(self, cr, uid, ids, context=None):
37 if context is None:
38 context = {}
39- project_obj = self.pool.get('project.project')
40+ task_pool = self.pool.get('project.task')
41 data_obj = self.pool.get('ir.model.data')
42 result = []
43 for proj in self.browse(cr, uid, ids, context=context):
44@@ -231,7 +248,7 @@
45 end_date = date(*time.strptime(proj.date,'%Y-%m-%d')[:3])
46 new_date_end = (datetime(*time.strptime(new_date_start,'%Y-%m-%d')[:3])+(end_date-start_date)).strftime('%Y-%m-%d')
47 context.update({'copy':True})
48- new_id = project_obj.copy(cr, uid, proj.id, default = {
49+ new_id = self.template_copy(cr, uid, proj.id, default = {
50 'name': proj.name +_(' (copy)'),
51 'state':'open',
52 'date_start':new_date_start,
53@@ -332,7 +349,7 @@
54
55 def onchange_planned(self, cr, uid, ids, planned = 0.0, effective = 0.0):
56 return {'value':{'remaining_hours': planned - effective}}
57-
58+
59 def onchange_project(self, cr, uid, id, project_id):
60 if not project_id:
61 return {}
62@@ -341,7 +358,7 @@
63 if partner_id:
64 return {'value':{'partner_id':partner_id.id}}
65 return {}
66-
67+
68 def _default_project(self, cr, uid, context=None):
69 if context is None:
70 context = {}
71@@ -349,6 +366,25 @@
72 return int(context['project_id'])
73 return False
74
75+ def duplicate_task(self, cr, uid, map_ids, context=None):
76+ for new in map_ids.values():
77+ task = self.browse(cr, uid, new, context)
78+ child_ids = [ ch.id for ch in task.child_ids]
79+ if task.child_ids:
80+ for child in task.child_ids:
81+ if child.id in map_ids.keys():
82+ child_ids.remove(child.id)
83+ child_ids.append(map_ids[child.id])
84+
85+ parent_ids = [ ch.id for ch in task.parent_ids]
86+ if task.parent_ids:
87+ for parent in task.parent_ids:
88+ if parent.id in map_ids.keys():
89+ parent_ids.remove(parent.id)
90+ parent_ids.append(map_ids[parent.id])
91+ #FIXME why there is already the copy and the old one
92+ self.write(cr, uid, new, {'parent_ids':[(6,0,set(parent_ids))], 'child_ids':[(6,0, set(child_ids))]})
93+
94 def copy_data(self, cr, uid, id, default={}, context=None):
95 default = default or {}
96 default.update({'work_ids':[], 'date_start': False, 'date_end': False, 'date_deadline': False})
97@@ -360,7 +396,7 @@
98 default['name'] = self.browse(cr, uid, id, context=context).name or ''
99 if not context.get('copy',False):
100 new_name = _("%s (copy)")%default.get('name','')
101- default.update({'name':new_name})
102+ default.update({'name':new_name})
103 return super(task, self).copy_data(cr, uid, id, default, context)
104
105 def _check_dates(self, cr, uid, ids, context=None):
106@@ -448,27 +484,33 @@
107 _order = "sequence,priority, date_start, name, id"
108
109 def _check_recursion(self, cr, uid, ids, context=None):
110- obj_task = self.browse(cr, uid, ids[0], context=context)
111- parent_ids = [x.id for x in obj_task.parent_ids]
112- children_ids = [x.id for x in obj_task.child_ids]
113-
114- if (obj_task.id in children_ids) or (obj_task.id in parent_ids):
115+ for id in ids:
116+ visited_branch = set()
117+ visited_node = set()
118+ res = self._check_cycle(cr, uid, id, visited_branch, visited_node, context=context)
119+ if not res:
120+ return False
121+
122+ return True
123+
124+ def _check_cycle(self, cr, uid, id, visited_branch, visited_node, context=None):
125+ if id in visited_branch: #Cycle
126 return False
127
128- while(ids):
129- cr.execute('SELECT DISTINCT task_id '\
130- 'FROM project_task_parent_rel '\
131- 'WHERE parent_id IN %s', (tuple(ids),))
132- child_ids = map(lambda x: x[0], cr.fetchall())
133- c_ids = child_ids
134- if (list(set(parent_ids).intersection(set(c_ids)))) or (obj_task.id in c_ids):
135+ if id in visited_node: #Already tested don't work one more time for nothing
136+ return True
137+
138+ visited_branch.add(id)
139+ visited_node.add(id)
140+
141+ #visit child using DFS
142+ task = self.browse(cr, uid, id, context=context)
143+ for child in task.child_ids:
144+ res = self._check_cycle(cr, uid, child.id, visited_branch, visited_node, context=context)
145+ if not res:
146 return False
147- while len(c_ids):
148- s_ids = self.search(cr, uid, [('parent_ids', 'in', c_ids)])
149- if (list(set(parent_ids).intersection(set(s_ids)))):
150- return False
151- c_ids = s_ids
152- ids = child_ids
153+
154+ visited_branch.remove(id)
155 return True
156
157 def _check_dates(self, cr, uid, ids, context=None):
158@@ -478,9 +520,9 @@
159 start = obj_task.date_start or False
160 end = obj_task.date_end or False
161 if start and end :
162- if start > end:
163+ if start > end:
164 return False
165- return True
166+ return True
167
168 _constraints = [
169 (_check_recursion, 'Error ! You cannot create recursive tasks.', ['parent_ids']),

Subscribers

People subscribed via source and target branches

to all changes: