Merge lp:~credativ/openobject-addons/elico-6.1-fixes-gap-analysis-template-management into lp:~openerp-community/openobject-addons/elico-6.1

Proposed by Tom Pickering
Status: Merged
Merged at revision: 54
Proposed branch: lp:~credativ/openobject-addons/elico-6.1-fixes-gap-analysis-template-management
Merge into: lp:~openerp-community/openobject-addons/elico-6.1
Diff against target: 718 lines (+450/-87)
8 files modified
gap_analysis/__openerp__.py (+2/-1)
gap_analysis/gap_analysis.py (+187/-52)
gap_analysis/gap_analysis.xml (+99/-29)
gap_analysis/wizard/__init__.py (+1/-0)
gap_analysis/wizard/import_from_sheet.py (+1/-2)
gap_analysis/wizard/import_from_tmpl.py (+12/-3)
gap_analysis/wizard/line_create_wizard.py (+75/-0)
gap_analysis/wizard/line_create_wizard_view.xml (+73/-0)
To merge this branch: bzr merge lp:~credativ/openobject-addons/elico-6.1-fixes-gap-analysis-template-management
Reviewer Review Type Date Requested Status
OpenERP Community (OBSOLETE) Pending
Review via email: mp+218422@code.launchpad.net

Description of the change

This branch adds several features to the Gap Analysis module which help to facilitate template-orientated workflows. These include:

- The ability to view associated Gap Analysis Lines and Gap Analysis Template Lines from a Functionality's form view.

- The ability to add Functionalities to Gap Analyses and Gap Analysis Templates from the 'All Functionalities' view.

- 'Group By...' options in the All 'Functionalities' view.

- Automatic updates to Gap Analysis Templates when a corresponding Functionality template is modified.

- Avoiding creation of duplicate Gap Analysis lines when importing from a Gap Analysis Template.

To post a comment you must log in.
53. By Tom Pickering

[FIX] Fixed traceback when changing the functionality of a non-saved Gap Analysis Line.

54. By Tom Pickering

[IMP] Duplicate functionality warning can now trigger when creating a new line in an existing Gap Analysis, if any duplicates already exist.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'gap_analysis/__openerp__.py'
--- gap_analysis/__openerp__.py 2013-06-22 02:18:01 +0000
+++ gap_analysis/__openerp__.py 2014-05-09 11:32:13 +0000
@@ -63,6 +63,7 @@
63 'gap_analysis_sequence.xml',63 'gap_analysis_sequence.xml',
64 'gap_analysis.xml',64 'gap_analysis.xml',
65 'wizard/import_from_tmpl.xml',65 'wizard/import_from_tmpl.xml',
66 'wizard/line_create_wizard_view.xml'
66 ],67 ],
67 #'demo_xml': ['gap_analysis_demo.xml'], 68 #'demo_xml': ['gap_analysis_demo.xml'],
68 'test': [],69 'test': [],
@@ -73,4 +74,4 @@
73 'certificate': '',74 'certificate': '',
74}75}
7576
76# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
77\ No newline at end of file77\ No newline at end of file
78# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
7879
=== modified file 'gap_analysis/gap_analysis.py'
--- gap_analysis/gap_analysis.py 2013-06-22 02:18:01 +0000
+++ gap_analysis/gap_analysis.py 2014-05-09 11:32:13 +0000
@@ -86,7 +86,8 @@
86 my_type = self.pool.get('gap_analysis.workload.type').browse(cr, uid, type_id)86 my_type = self.pool.get('gap_analysis.workload.type').browse(cr, uid, type_id)
87 val['duration'] = my_type.duration87 val['duration'] = my_type.duration
88 return {'value': val}88 return {'value': val}
89 89
90
90gap_analysis_workload()91gap_analysis_workload()
9192
9293
@@ -150,33 +151,129 @@
150 _name = "gap_analysis.functionality"151 _name = "gap_analysis.functionality"
151 _description = "Gap Analysis Functionalities"152 _description = "Gap Analysis Functionalities"
152 153
154
155 def _search_ga_lines(self, cr, uid, ids, field_names, arg=None, context=None, tmpl=False):
156 if context is None:
157 context = {}
158
159 ga_obj = self.pool.get('gap_analysis')
160 ga_line_obj = self.pool.get('gap_analysis.line')
161 func_obj = self.pool.get('gap_analysis.functionality')
162
163 line_ids = ga_line_obj.search(cr, uid, [('functionality','=', ids[0])], context=context)
164
165 lids_to_gids = {}
166 tmpl_lids = []
167 ga_obj = self.pool.get('gap_analysis')
168 gap_ids = ga_line_obj.read(cr, uid, line_ids, ['gap_id'], context=context)
169
170 for gap_id in gap_ids:
171 lids_to_gids[gap_id['id']] = gap_id['gap_id'][0]
172
173 tmpl_checks = ga_obj.read(cr, uid, [gid['gap_id'][0] for gid in gap_ids], ['is_tmpl'], context=context)
174 gids_to_checks = dict(zip([c['id'] for c in tmpl_checks], [c['is_tmpl'] == tmpl for c in tmpl_checks]))
175
176 for lid in lids_to_gids.keys():
177 if gids_to_checks[lids_to_gids[lid]]:
178 tmpl_lids.append(lid)
179
180 return {ids[0] : [l for l in line_ids if l in tmpl_lids]}
181
182
183 def _search_ga_tmpl_lines(self, cr, uid, ids, field_names, arg=None, context=None):
184 return self._search_ga_lines(cr, uid, ids, field_names, arg=arg, context=context, tmpl=True)
185
186
187 def _search_ga_non_tmpl_lines(self, cr, uid, ids, field_names, arg=None, context=None):
188 return self._search_ga_lines(cr, uid, ids, field_names, arg=arg, context=context, tmpl=False)
189
190
153 _columns = {191 _columns = {
154 'name': fields.char('Functionality', size=256, required=True, translate=True),192 'name': fields.char('Functionality', size=256, required=True, translate=True),
155 'description': fields.text('Description'),193 'description': fields.text('Description'),
156 'category': fields.many2one('gap_analysis.functionality.category', 'Category', required=True, select=True),194 'category': fields.many2one('gap_analysis.functionality.category', 'Category', required=True, select=True),
157 'is_tmpl': fields.boolean('Template ?', help='This Functionality is a Template ?'),195 'is_tmpl': fields.boolean('Template ?', help='This Functionality is a Template ?'),
158 'proposed': fields.boolean('Propose as template ?'),196 'proposed': fields.boolean('Propose as template ?'),
159 #### Default values (Templating) ####197 #### Default values (Templating) ####
160 'workloads': fields.one2many('gap_analysis.workload', 'fct_id', 'Default Workloads'),198 'workloads': fields.one2many('gap_analysis.workload', 'fct_id', 'Default Workloads'),
161 'openerp_fct': fields.many2one('gap_analysis.openerp', 'Default OpenERP feature', select=True),199 'openerp_fct': fields.many2one('gap_analysis.openerp', 'Default OpenERP feature', select=True),
162 'critical': fields.integer('Default Critical Level', help='Indicator to specify the importance of this functionality in the project.'),200 'critical': fields.integer('Default Critical Level', help='Indicator to specify the importance of this functionality in the project.'),
163 'testing': fields.float('Test (hour)'),201 'testing': fields.float('Test (hour)'),
164 'effort': fields.many2one('gap_analysis.effort', 'Default Effort', help="Development Effort for this functionality."),202 'effort': fields.many2one('gap_analysis.effort', 'Default Effort', help="Development Effort for this functionality."),
165 'duration_wk': fields.float('Default Duration (hour)', help='Since this effort has no pre-defined duration, you must set one.'),203 'duration_wk': fields.float('Default Duration (hour)', help='Since this effort has no pre-defined duration, you must set one.'),
166 'unknown_wk': fields.boolean('Must set the duration manually ? (Default)',),204 'unknown_wk': fields.boolean('Must set the duration manually ? (Default)',),
205 'ga_lines': fields.function(_search_ga_non_tmpl_lines, type='one2many', relation='gap_analysis.line', method=True, string='Gap Analysis Lines'),
206 'ga_tmpl_lines': fields.function(_search_ga_tmpl_lines, type='one2many', relation='gap_analysis.line', method=True, string='Gap Analysis Template Lines'),
167 }207 }
208
209
210 def open_line_wizard(self, cr, uid, ids, context=None):
211 if context is None:
212 context={}
213
214 title = context.get('default_tmpl', False) and 'Create New Template Entry' or 'Create New Entry'
215
216 return {
217 'type' : 'ir.actions.act_window',
218 'name' : title,
219 'res_model': 'gap_analysis.line_create_wizard',
220 'view_type' : 'form',
221 'view_mode' : 'form',
222 'target' : 'new',
223 'context' : context,
224 }
168 225
226
227 def onchange_is_tmpl(self, cr, uid, ids, is_tmpl, context=None):
228 if context is None:
229 context = {}
230
231 if not is_tmpl or not len(ids):
232 return {}
233
234 ga_line_pool = self.pool.get('gap_analysis.line')
235 related_lines = ga_line_pool.search(cr, uid, [('functionality','=',ids[0])], context=context)
236
237 if not related_lines:
238 return {}
239
240 source_line = max(related_lines)
241 fields_to_read = ['workloads', 'openerp_fct', 'critical', 'testing', 'effort', 'duration_wk', 'unknown_wk']
242 val = ga_line_pool.read(cr, uid, source_line, fields_to_read, context=context)
243
244 if val.get('workloads', False):
245 wkld_pool = self.pool.get('gap_analysis.workload')
246 new_wklds = []
247 for wkld in val['workloads']:
248 wkld_data = wkld_pool.read(cr, uid, wkld, ['type', 'duration'])
249 new_wklds.append({'fct_id' : ids[0], 'gap_line_id' : False, 'type' : wkld_data['type'][0], 'duration' : wkld_data['duration']})
250 val['workloads'] = new_wklds
251
252 return {'value' : val}
253
254
169 def onchange_effort_id(self, cr, uid, ids, effort_id, unknown_wk):255 def onchange_effort_id(self, cr, uid, ids, effort_id, unknown_wk):
170 val = {}256 val = {}
171 my_effort = self.pool.get('gap_analysis.effort').browse(cr, uid, effort_id)257 if effort_id:
172 val['unknown_wk'] = my_effort.unknown258 my_effort = self.pool.get('gap_analysis.effort').browse(cr, uid, effort_id)
259 val['unknown_wk'] = my_effort.unknown
260 else:
261 val['unknown_wk'] = False
173 return {'value': val}262 return {'value': val}
174 263
175 264
176 def write(self, cr, uid, ids, vals, context=None):265 def write(self, cr, uid, ids, vals, context=None):
177 if 'is_tmpl' in vals and vals['is_tmpl'] == True:266 if 'is_tmpl' in vals and vals['is_tmpl'] == True:
178 vals['proposed'] = False267 vals['proposed'] = False
179 return super(gap_analysis_functionality, self).write(cr, uid, ids, vals, context=context)268 res = super(gap_analysis_functionality, self).write(cr, uid, ids, vals, context=context)
269 if res:
270 id_list = isinstance(ids, list) and ids[:] or [ids]
271 line_pool = self.pool.get('gap_analysis.line')
272 for fid in id_list:
273 lids = line_pool.search(cr, uid, [('gap_id.is_tmpl','=',True),('functionality','=',fid)], context=context)
274 line_pool.set_values_by_fct(cr, uid, lids, fid, context=context)
275
276 return res
180 277
181gap_analysis_functionality()278gap_analysis_functionality()
182279
@@ -351,7 +448,7 @@
351class gap_analysis_line(osv.osv):448class gap_analysis_line(osv.osv):
352 _name = "gap_analysis.line"449 _name = "gap_analysis.line"
353 _description = "Gap-analysis Lines"450 _description = "Gap-analysis Lines"
354 451
355 def _estimated_line_time_cost(self, cursor, uid, ids, fields, arg, context=None):452 def _estimated_line_time_cost(self, cursor, uid, ids, fields, arg, context=None):
356 result = {}453 result = {}
357 gap = False454 gap = False
@@ -404,39 +501,71 @@
404 if w.type.id == arg:501 if w.type.id == arg:
405 amount += w.duration 502 amount += w.duration
406 return amount503 return amount
407 504
408 505
409 def onchange_functionality_id(self, cr, uid, ids, functionality_id, gap_line_id):506 def set_values_by_fct(self, cr, uid, ids, fct_id, ret_fmt_onchange=False, context=None):
410 val = {}507 vals = []
411 functionality_tmpl = self.pool.get('gap_analysis.functionality').browse(cr, uid, functionality_id)508 fct_tmpl = self.pool.get('gap_analysis.functionality').browse(cr, uid, fct_id)
412 if functionality_tmpl.effort:509 id_list = isinstance(ids, list) and ids[:] or [ids]
413 val['effort'] = functionality_tmpl.effort.id510 for lid in id_list:
414 if functionality_tmpl.category:511 val = {}
415 val['category'] = functionality_tmpl.category.id512 if fct_tmpl.effort:
416 if functionality_tmpl.testing:513 val['effort'] = fct_tmpl.effort.id
417 val['testing'] = functionality_tmpl.testing514 if fct_tmpl.category:
418 if functionality_tmpl.unknown_wk:515 val['category'] = fct_tmpl.category.id
419 val['unknown_wk'] = functionality_tmpl.unknown_wk516 if fct_tmpl.testing:
420 if functionality_tmpl.duration_wk:517 val['testing'] = fct_tmpl.testing
421 val['duration_wk'] = functionality_tmpl.duration_wk518 if fct_tmpl.unknown_wk:
422 if functionality_tmpl.critical:519 val['unknown_wk'] = fct_tmpl.unknown_wk
423 val['critical'] = functionality_tmpl.critical520 if fct_tmpl.duration_wk:
424 if functionality_tmpl.openerp_fct:521 val['duration_wk'] = fct_tmpl.duration_wk
425 val['openerp_fct'] = functionality_tmpl.openerp_fct.id522 if fct_tmpl.critical:
426 if functionality_tmpl.workloads:523 val['critical'] = fct_tmpl.critical
427 workload_pool = self.pool.get('gap_analysis.workload')524 if fct_tmpl.openerp_fct:
428 my_workloads = []525 val['openerp_fct'] = fct_tmpl.openerp_fct.id
429 for workload in functionality_tmpl.workloads:526 if fct_tmpl.workloads:
430 workload_vals = {'type':workload.type.id,'duration':workload.duration,}527 workload_pool = self.pool.get('gap_analysis.workload')
431 if gap_line_id:528 my_workloads = []
432 workload_vals['gap_line_id'] = gap_line_id529 for workload in fct_tmpl.workloads:
433 workload_id = workload_pool.create(cr, uid, workload_vals)530 workload_vals = {'type':workload.type.id,'duration':workload.duration,}
434 if workload_id:531 if lid:
435 my_workloads.append(workload_id)532 workload_vals['gap_line_id'] = lid
436 if my_workloads:533 my_workloads.append(workload_vals)
437 val['workloads'] = my_workloads534 val['workloads'] = my_workloads
438 535 if ret_fmt_onchange:
439 return {'value': val}536 vals.append(val)
537 else:
538 my_workloads = val.get('workloads', False)
539 old_wkld_data = self.read(cr, uid, lid, ['workloads'], context=context)
540 if old_wkld_data:
541 old_wklds = old_wkld_data['workloads']
542 wkld_unlink_tuples = [(2, wid) for wid in old_wklds]
543 val['workloads'] = wkld_unlink_tuples
544 self.write(cr, uid, lid, val, context=context)
545 if my_workloads:
546 wkld_tuples = []
547 for wkld in my_workloads:
548 wkld_tuples.append((0, 0, wkld))
549 self.write(cr, uid, lid, {'workloads':wkld_tuples}, context=context)
550 return ret_fmt_onchange and vals or True
551
552
553 def onchange_functionality_id(self, cr, uid, ids, fct_id, gap_id, context=None):
554 ret = {}
555 ids = isinstance(ids, list) and ids or [ids]
556 val = self.set_values_by_fct(cr, uid, ids, fct_id, ret_fmt_onchange=True, context=context)
557 ret.update({'value' : val[0]})
558
559 if gap_id:
560 ga_lines = self.search(cr, uid, [('gap_id','=',gap_id),('id','!=',ids[0])], context=context)
561 if ga_lines:
562 ga_fcts = self.read(cr, uid, ga_lines, ['functionality'], context=context)
563 if fct_id in [fct['functionality'][0] for fct in ga_fcts]:
564 ret.update({'warning' : {
565 'title' : 'Warning: Functionality Duplication.',
566 'message' : 'This functionality already exists within this Gap Analysis.',
567 }})
568 return ret
440 569
441 570
442 def onchange_effort_id(self, cr, uid, ids, effort_id, unknown_wk):571 def onchange_effort_id(self, cr, uid, ids, effort_id, unknown_wk):
@@ -444,8 +573,13 @@
444 my_effort = self.pool.get('gap_analysis.effort').browse(cr, uid, effort_id)573 my_effort = self.pool.get('gap_analysis.effort').browse(cr, uid, effort_id)
445 val['unknown_wk'] = my_effort.unknown574 val['unknown_wk'] = my_effort.unknown
446 return {'value': val}575 return {'value': val}
447 576
448 577
578 def _get_dummy_gap_is_tmpl(self, cr, uid, ids, fields, arg, context=None):
579 gid = self.read(cr, uid, ids[0], ['gap_id'], context=context)['gap_id'][0]
580 return {ids[0] : self.pool.get('gap_analysis').read(cr, uid, gid, ['is_tmpl'], context=context)['is_tmpl']}
581
582
449 _columns = {583 _columns = {
450 'gap_id': fields.many2one('gap_analysis', 'Gap-analysis', required=True, ondelete='cascade', select=True, readonly=True),584 'gap_id': fields.many2one('gap_analysis', 'Gap-analysis', required=True, ondelete='cascade', select=True, readonly=True),
451 'seq': fields.char('Sequence', size=48),585 'seq': fields.char('Sequence', size=48),
@@ -463,6 +597,7 @@
463 'effort': fields.many2one('gap_analysis.effort', 'Effort', help="Development Effort for this functionality."),597 'effort': fields.many2one('gap_analysis.effort', 'Effort', help="Development Effort for this functionality."),
464 'duration_wk': fields.float('Duration (hour)', help='Since this effort has no pre-defined duration, you must set one.'),598 'duration_wk': fields.float('Duration (hour)', help='Since this effort has no pre-defined duration, you must set one.'),
465 'unknown_wk': fields.boolean('Must set the duration manually ?',),599 'unknown_wk': fields.boolean('Must set the duration manually ?',),
600 'dummy_gap_is_tmpl': fields.function(_get_dummy_gap_is_tmpl, type='boolean', name='dummy_gap_is_tmpl', method=True),
466 }601 }
467 _defaults = {602 _defaults = {
468 'unknown_wk': lambda *a: False,603 'unknown_wk': lambda *a: False,
@@ -475,4 +610,4 @@
475 610
476gap_analysis_line()611gap_analysis_line()
477612
478# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
479\ No newline at end of file613\ No newline at end of file
614# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
480615
=== modified file 'gap_analysis/gap_analysis.xml'
--- gap_analysis/gap_analysis.xml 2013-06-22 02:18:01 +0000
+++ gap_analysis/gap_analysis.xml 2014-05-09 11:32:13 +0000
@@ -24,36 +24,104 @@
24 <form string="Gap Analysis Functionalities">24 <form string="Gap Analysis Functionalities">
25 <field name="category"/>25 <field name="category"/>
26 <field name="name"/>26 <field name="name"/>
27 <field name="is_tmpl" groups="gap_analysis.res_group_gap1"/>27 <field name="is_tmpl" groups="gap_analysis.res_group_gap1" on_change="onchange_is_tmpl(is_tmpl)"/>
28 <field name="proposed" attrs="{'invisible':[('is_tmpl','=',True)]}"/>28 <field name="proposed" attrs="{'invisible':[('is_tmpl','=',True)]}"/>
29 <newline/>29 <newline/>
30 <separator string="Description" colspan="4"/>30
31 <field name="description" colspan="4" nolabel="1"/>31 <notebook colspan="4">
32 <newline/>32 <page string="Details">
33 <group groups="gap_analysis.res_group_gap1" attrs="{'invisible':[('is_tmpl','=',False)]}" colspan="4" col="4">33 <separator string="Description" colspan="4"/>
34 <separator colspan="4" string="Template Default Values"/>34 <field name="description" colspan="4" nolabel="1"/>
35 <newline/>
36 <group groups="gap_analysis.res_group_gap1" attrs="{'invisible':[('is_tmpl','=',False)]}" colspan="4" col="4">
37 <separator colspan="4" string="Default Values"/>
35 <field name="critical"/>38 <field name="critical"/>
36 <field name="openerp_fct"/>39 <field name="openerp_fct"/>
37 <field name="effort" on_change="onchange_effort_id(effort,unknown_wk)"/>40 <field name="effort" on_change="onchange_effort_id(effort,unknown_wk)"/>
38 <field name="unknown_wk" invisible="1"/>41 <field name="unknown_wk" invisible="1"/>
39 <field name="duration_wk" attrs="{'invisible':[('unknown_wk','=',False)]}"/>42 <field name="duration_wk" attrs="{'invisible':[('unknown_wk','=',False)]}"/>
40 <field name="testing"/>43 <field name="testing"/>
41 <newline/>44 <newline/>
45
42 <separator colspan="4" string="Workloads"/>46 <separator colspan="4" string="Workloads"/>
43 <field colspan="4" name="workloads" nolabel="1" widget="one2many_list">47 <field colspan="4" name="workloads" nolabel="1" widget="one2many_list">
44 <form string="Workloads">48 <form string="Workloads">
45 <field name="type" on_change="onchange_type_id(type)" colspan="4"/>49 <field name="type" on_change="onchange_type_id(type)" colspan="4"/>
46 <field name="duration"/>50 <field name="duration"/>
47 </form>51 </form>
48 <tree string="Workloads">52 <tree>
49 <field name="type"/>53 <field name="type"/>
50 <field name="duration"/>54 <field name="duration"/>
51 </tree>55 </tree>
52 </field>56 </field>
53 </group>57 <newline/>
58 </group>
59 </page>
60
61 <page string="Analyses">
62 <group colspan="4" col="4">
63 <separator colspan="4" string="Instances"/>
64 <field colspan="4" name="ga_lines" nolabel="1">
65 <tree colors="grey:keep==False;">
66 <field name="gap_id" string="Gap Analysis"/>
67 <field name="code"/>
68 <field name="keep" invisible="1"/>
69 <field name="phase"/>
70 <field name="critical"/>
71 <field name="effort"/>
72 <field name="testing"/>
73 <field name="duration_wk"/>
74 <field name="total_time"/>
75 <field name="total_cost"/>
76 </tree>
77 </field>
78 <button name="open_line_wizard" string="Add to Analysis" type="object" icon="gtk-add" context="{'default_tmpl':False}"/>
79 </group>
80 <group attrs="{'invisible':[('is_tmpl','=',False)]}" colspan="4" col="4">
81 <separator colspan="4" string="Gap Templates"/>
82 <field colspan="4" name="ga_tmpl_lines" nolabel="1" options="{'deletable': false}">
83 <tree colors="grey:keep==False;">
84 <field name="gap_id" string="Template"/>
85 <field name="code"/>
86 <field name="keep" invisible="1"/>
87 <field name="phase"/>
88 <field name="critical"/>
89 <field name="effort"/>
90 <field name="testing"/>
91 <field name="duration_wk"/>
92 </tree>
93 </field>
94 <button name="open_line_wizard" string="Add to Template" type="object" icon="gtk-add" context="{'default_tmpl':True}"/>
95 </group>
96 </page>
97 </notebook>
54 </form>98 </form>
55 </field>99 </field>
56 </record>100 </record>
101
102 <record id="view_gap_analysis_functionality_filter" model="ir.ui.view">
103 <field name="name">gap_analysis.functionality.search</field>
104 <field name="model">gap_analysis.functionality</field>
105 <field name="type">search</field>
106 <field name="arch" type="xml">
107 <search string="Search Functionality">
108 <filter string="Template" icon="star-on" domain="[('is_tmpl','=',True)]"/>
109 <filter string="Regular" icon="star-off" domain="[('is_tmpl','=',False)]"/>
110 <separator orientation="vertical"/>
111 <filter string="Proposed" icon="terp-idea" domain="[('proposed','=',True)]"/>
112 <field name="category"/>
113 <field name="name" string="Name"/>
114 <field name="description"/>
115 <field name="openerp_fct" string="OpenERP Feature"/>
116 <newline/>
117 <group expand="0" string="Group By..." colspan="4">
118 <filter string="Category" icon="terp-stage" context="{'group_by':'category'}"/>
119 <filter string="Critical Level" icon="terp-gnome-cpu-frequency-applet+" context="{'group_by':'critical'}"/>
120 <filter string="Effort" icon="terp-project" context="{'group_by':'effort'}"/>
121 </group>
122 </search>
123 </field>
124 </record>
57 125
58 <!-- Functionality Categories -->126 <!-- Functionality Categories -->
59 <record id="view_gap_analysis_functionality_category_tree" model="ir.ui.view">127 <record id="view_gap_analysis_functionality_category_tree" model="ir.ui.view">
@@ -202,19 +270,20 @@
202 <form string="Functionalities">270 <form string="Functionalities">
203 <group colspan="4" col="4">271 <group colspan="4" col="4">
204 <field name="id" invisible="1"/>272 <field name="id" invisible="1"/>
205 <field name="functionality" on_change="onchange_functionality_id(functionality,id)" colspan="4" domain="[('is_tmpl','=',True)]"/>273 <field name="dummy_gap_is_tmpl" invisible="1"/>
206 <field name="category"/>274 <field name="functionality" on_change="onchange_functionality_id(functionality,parent.id)" colspan="4" domain="[('is_tmpl','=',True)]"/>
275 <field name="category" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
207 <field name="keep"/>276 <field name="keep"/>
208 <field name="critical"/>277 <field name="critical" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
209 <field name="openerp_fct"/>278 <field name="openerp_fct" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
210 <field name="contributors"/>279 <field name="contributors"/>
211 <field name="testing"/>280 <field name="testing" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
212 <field name="effort" on_change="onchange_effort_id(effort,unknown_wk)"/>281 <field name="effort" on_change="onchange_effort_id(effort,unknown_wk)" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
213 <field name="unknown_wk" invisible="1"/>282 <field name="unknown_wk" invisible="1" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
214 <field name="duration_wk" attrs="{'invisible':[('unknown_wk','=',False)]}"/>283 <field name="duration_wk" attrs="{'invisible':[('unknown_wk','=',False)],'readonly':[('dummy_gap_is_tmpl','=',True)]}"/>
215 <newline/>284 <newline/>
216 <separator colspan="4" string="Workloads"/>285 <separator colspan="4" string="Workloads"/>
217 <field colspan="4" name="workloads" nolabel="1" widget="one2many_list">286 <field colspan="4" name="workloads" nolabel="1" widget="one2many_list" attrs="{'readonly':[('dummy_gap_is_tmpl','=',True)]}">
218 <form string="Workloads">287 <form string="Workloads">
219 <field name="type" on_change="onchange_type_id(type)"/>288 <field name="type" on_change="onchange_type_id(type)"/>
220 <field name="duration"/>289 <field name="duration"/>
@@ -295,6 +364,7 @@
295 <field name="res_model">gap_analysis.functionality</field>364 <field name="res_model">gap_analysis.functionality</field>
296 <field name="view_type">form</field>365 <field name="view_type">form</field>
297 <field name="view_mode">tree,form</field>366 <field name="view_mode">tree,form</field>
367 <field name="search_view">gap_analysis.view_gap_analysis_functionality_filter</field>
298 </record>368 </record>
299 <record id="act_gap_analysis_fct_tmpl" model="ir.actions.act_window">369 <record id="act_gap_analysis_fct_tmpl" model="ir.actions.act_window">
300 <field name="name">Functionality Templates</field>370 <field name="name">Functionality Templates</field>
@@ -376,4 +446,4 @@
376 <menuitem id="menu_gap_022" name="Efforts" parent="menu_gap_02" sequence="6" action="act_gap_analysis_effort" />446 <menuitem id="menu_gap_022" name="Efforts" parent="menu_gap_02" sequence="6" action="act_gap_analysis_effort" />
377 <menuitem id="menu_gap_023" name="OpenERP Features" parent="menu_gap_02" sequence="9" action="act_gap_analysis_openerp" />447 <menuitem id="menu_gap_023" name="OpenERP Features" parent="menu_gap_02" sequence="9" action="act_gap_analysis_openerp" />
378 </data>448 </data>
379</openerp>
380\ No newline at end of file449\ No newline at end of file
450</openerp>
381451
=== modified file 'gap_analysis/wizard/__init__.py'
--- gap_analysis/wizard/__init__.py 2013-06-22 02:18:01 +0000
+++ gap_analysis/wizard/__init__.py 2014-05-09 11:32:13 +0000
@@ -22,5 +22,6 @@
2222
23import import_from_tmpl23import import_from_tmpl
24import import_from_sheet24import import_from_sheet
25import line_create_wizard
2526
26# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:27# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2728
=== modified file 'gap_analysis/wizard/import_from_sheet.py'
--- gap_analysis/wizard/import_from_sheet.py 2013-06-22 02:18:01 +0000
+++ gap_analysis/wizard/import_from_sheet.py 2014-05-09 11:32:13 +0000
@@ -222,8 +222,7 @@
222 222
223 # Check Functionality223 # Check Functionality
224 fct_ids = g_fct_pool.search(cr, uid, [('name','ilike',gap_line.functionality)])224 fct_ids = g_fct_pool.search(cr, uid, [('name','ilike',gap_line.functionality)])
225 if True:225 if not fct_ids:
226# if not fct_ids:
227 # Create Functionality226 # Create Functionality
228 fct_id = g_fct_pool.create(cr, uid, {'name':gap_line.functionality,'description': gap_line.function_desc,'category':gap_line.category,})227 fct_id = g_fct_pool.create(cr, uid, {'name':gap_line.functionality,'description': gap_line.function_desc,'category':gap_line.category,})
229 print('Gap Import: Fct %s created (%s)'%(gap_line.functionality,fct_id))228 print('Gap Import: Fct %s created (%s)'%(gap_line.functionality,fct_id))
230229
=== modified file 'gap_analysis/wizard/import_from_tmpl.py'
--- gap_analysis/wizard/import_from_tmpl.py 2013-06-22 02:18:01 +0000
+++ gap_analysis/wizard/import_from_tmpl.py 2014-05-09 11:32:13 +0000
@@ -38,10 +38,19 @@
38 this = self.browse(cr, uid, ids[0], context=context)38 this = self.browse(cr, uid, ids[0], context=context)
39 gap_line_pool = self.pool.get('gap_analysis.line')39 gap_line_pool = self.pool.get('gap_analysis.line')
40 workload_pool = self.pool.get('gap_analysis.workload')40 workload_pool = self.pool.get('gap_analysis.workload')
41 41
42 for id in context.get('active_ids', []): #for each gap in which we want to import stuff42 for id in context.get('active_ids', []): #for each gap in which we want to import stuff
43 current_line_ids = gap_line_pool.search(cr, uid, [('gap_id','=',id)], context=context)
44 current_fcts = gap_line_pool.read(cr, uid, current_line_ids, ['functionality'])
45 current_fct_ids = [f['functionality'][0] for f in current_fcts]
46
43 #copy gap_line with functionalities and workloads47 #copy gap_line with functionalities and workloads
44 for gap_line in this.template.gap_lines:48 for gap_line in this.template.gap_lines:
49
50 if gap_line.functionality.id in current_fct_ids:
51 # Functionality already exists in the Gap.
52 continue
53
45 line_vals = {54 line_vals = {
46 'gap_id': id,55 'gap_id': id,
47 'functionality': gap_line.functionality.id,56 'functionality': gap_line.functionality.id,
@@ -54,7 +63,7 @@
54 'duration_wk': gap_line.duration_wk,63 'duration_wk': gap_line.duration_wk,
55 'unknown_wk': gap_line.unknown_wk,64 'unknown_wk': gap_line.unknown_wk,
56 'testing': gap_line.testing,65 'testing': gap_line.testing,
57 'category': gap_line.category,66 'category': gap_line.category.id,
58 }67 }
59 gap_line_id = gap_line_pool.create(cr, uid, line_vals, context=context)68 gap_line_id = gap_line_pool.create(cr, uid, line_vals, context=context)
60 69
@@ -70,4 +79,4 @@
7079
71gap_analysis_import_from_tmpl()80gap_analysis_import_from_tmpl()
7281
73# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
74\ No newline at end of file82\ No newline at end of file
83# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
7584
=== added file 'gap_analysis/wizard/line_create_wizard.py'
--- gap_analysis/wizard/line_create_wizard.py 1970-01-01 00:00:00 +0000
+++ gap_analysis/wizard/line_create_wizard.py 2014-05-09 11:32:13 +0000
@@ -0,0 +1,75 @@
1
2
3from osv import osv, fields
4from osv.osv import except_osv
5from tools.translate import _
6
7class line_create_wizard(osv.TransientModel):
8 _name = 'gap_analysis.line_create_wizard'
9
10 _columns = {
11 'gap_id' : fields.many2one('gap_analysis', 'Gap Analysis', required=True),
12 'tmpl' : fields.boolean('', help='This is used to control the gap_id domain presented in the wizard'),
13 }
14
15
16 def create_line(self, cr, uid, ids, context=None):
17 if context is None:
18 context = {}
19
20 fct_fields = [
21 'workloads',
22 'critical',
23 'testing',
24 'duration_wk',
25 'unknown_wk',
26 ]
27
28 fct_rel_fields = [
29 'category',
30 'openerp_fct',
31 'effort',
32 ]
33
34 line_pool = self.pool.get('gap_analysis.line')
35 fct_pool = self.pool.get('gap_analysis.functionality')
36 self_browse = self.browse(cr, uid, ids[0], context=context)
37
38 # If adding to a template, make sure all the functionalities are also templates.
39 if self_browse.gap_id.is_tmpl:
40 tmpl_stats = fct_pool.read(cr, uid, context['active_ids'], ['is_tmpl','name'], context=context)
41 if not all([tmpl_stat['is_tmpl'] for tmpl_stat in tmpl_stats]):
42 non_tmpls = [tmpl_stat['name'] for tmpl_stat in tmpl_stats if not tmpl_stat['is_tmpl']]
43 raise except_osv(
44 _('Error: Non-template functionalities may not be added to a Gap Analysis Template.'),
45 _('Please configure these functionalities accordingly and retry:\n\n%s') % ('\n\n'.join(non_tmpls))
46 )
47
48 fct_defs = fct_pool.read(cr, uid, context['active_ids'], fct_fields + fct_rel_fields, context=context)
49 gap_id = self_browse.gap_id.id
50 new_params = {'gap_id' : gap_id}
51
52 for fct_def in fct_defs:
53 for rel_field in fct_rel_fields:
54 fct_def[rel_field] = fct_def[rel_field] and fct_def[rel_field][0]
55
56 if fct_def['workloads']:
57 wkld_pool = self.pool.get('gap_analysis.workload')
58 wkld_cps = []
59 for wkld in fct_def['workloads']:
60 wkld_cp = wkld_pool.copy(cr, uid, wkld, {'fct_id' : False}, context=context)
61 wkld_cps.append(wkld_cp)
62 fct_def['workloads'] = [(6, 0, wkld_cps)]
63
64 new_params.update(functionality=fct_def['id'])
65
66 fct_def.update(new_params)
67 del fct_def['id']
68 line_pool.create(cr, uid, fct_def, context=context)
69
70 return {'type' : 'ir.actions.act_window_close'}
71
72
73line_create_wizard()
74
75# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
076
=== added file 'gap_analysis/wizard/line_create_wizard_view.xml'
--- gap_analysis/wizard/line_create_wizard_view.xml 1970-01-01 00:00:00 +0000
+++ gap_analysis/wizard/line_create_wizard_view.xml 2014-05-09 11:32:13 +0000
@@ -0,0 +1,73 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<openerp>
4 <data>
5 <record id="line_create_wizard_view" model="ir.ui.view">
6 <field name="name">gap.analysis.line.create.wizard</field>
7 <field name="model">gap_analysis.line_create_wizard</field>
8 <field name="type">form</field>
9 <field name="arch" type="xml">
10 <form string="Create Gap Analysis Lines">
11 <group col="2" colspan="2">
12 <field name="tmpl" invisible="1"/>
13 <field name="gap_id" domain="[('is_tmpl','=',tmpl),'|',('is_tmpl','=',True),('state','=','draft')]"/>
14 </group>
15 <group colspan="2"/>
16 <separator colspan="4"/>
17 <group colspan="2"/>
18 <group col="2" colspan="2">
19 <button icon="gtk-cancel" special="cancel" string="Cancel" colspan="1"/>
20 <button icon="gtk-apply" name="create_line" string="Create" type="object" colspan="1" default_focus="1"/>
21 </group>
22 </form>
23 </field>
24 </record>
25
26 <record model="ir.actions.act_window" id="action_gap_analysis_mass_add_to_analysis">
27 <field name="name">Add to Analysis</field>
28 <field name="type">ir.actions.act_window</field>
29 <field name="view_id" ref="line_create_wizard_view"/>
30 <field name="domain">[]</field>
31 <field name="context">{'default_tmpl' : False}</field>
32 <field name="res_model">gap_analysis.line_create_wizard</field>
33 <field name="view_type">form</field>
34 <field name="view_mode">form</field>
35 <field name="usage">menu</field>
36 <field name="target">new</field>
37 </record>
38
39 <record model="ir.values" id="values_gap_analysis_mass_add_to_analysis">
40 <field name="model_id" ref="gap_analysis.model_gap_analysis_functionality" />
41 <field name="object" eval="1" />
42 <field name="name">Add to Analysis</field>
43 <field name="key2">client_action_multi</field>
44 <field name="value" eval="'ir.actions.act_window,' + str(ref('action_gap_analysis_mass_add_to_analysis'))" />
45 <field name="key">action</field>
46 <field name="model">gap_analysis.functionality</field>
47 </record>
48
49 <record model="ir.actions.act_window" id="action_gap_analysis_mass_add_to_template">
50 <field name="name">Add to Template</field>
51 <field name="type">ir.actions.act_window</field>
52 <field name="view_id" ref="line_create_wizard_view"/>
53 <field name="domain">[]</field>
54 <field name="context">{'default_tmpl' : True}</field>
55 <field name="res_model">gap_analysis.line_create_wizard</field>
56 <field name="view_type">form</field>
57 <field name="view_mode">form</field>
58 <field name="usage">menu</field>
59 <field name="target">new</field>
60 </record>
61
62 <record model="ir.values" id="values_gap_analysis_mass_add_to_template">
63 <field name="model_id" ref="gap_analysis.model_gap_analysis_functionality" />
64 <field name="object" eval="1" />
65 <field name="name">Add to Template</field>
66 <field name="key2">client_action_multi</field>
67 <field name="value" eval="'ir.actions.act_window,' + str(ref('action_gap_analysis_mass_add_to_template'))" />
68 <field name="key">action</field>
69 <field name="model">gap_analysis.functionality</field>
70 </record>
71
72 </data>
73</openerp>

Subscribers

People subscribed via source and target branches