← Back to team overview

openerp-dev-web team mailing list archive

lp:~openerp-dev/openobject-addons/training_osv_memory_wizard_trainee_degree into lp:~openobject-training/openobject-addons/training_with_history

 

gpa(Open ERP) has proposed merging lp:~openerp-dev/openobject-addons/training_osv_memory_wizard_trainee_degree into lp:~openobject-training/openobject-addons/training_with_history.

Requested reviews:
  Bhumika (OpenERP) (sbh-openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/training_osv_memory_wizard_trainee_degree/+merge/53959

traing module wizard converted to osv_memory wizard and trainig_degree module improvement
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/training_osv_memory_wizard_trainee_degree/+merge/53959
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-addons/training_osv_memory_wizard_trainee_degree.
=== modified file 'training/__openerp__.py'
--- training/__openerp__.py	2011-03-14 10:48:46 +0000
+++ training/__openerp__.py	2011-03-18 09:03:31 +0000
@@ -77,6 +77,13 @@
         'security/training_security.xml',
         'security/roles.xml',
         'security/ir.model.access.csv',
+        'wizard/training_subscription_session.xml',
+        'wizard/validate_course_view.xml',
+        'wizard/training_subscription_line_confirm.xml',
+        'wizard/training_create_offer.xml',
+        'wizard/training_create_block_offer.xml',
+        'wizard/training_subscription_second_line.xml',
+
 
         # TODO move this into the base_contact module
         'contact_security/groups.xml',

=== modified file 'training/training.py'
--- training/training.py	2011-03-14 10:48:46 +0000
+++ training/training.py	2011-03-18 09:03:31 +0000
@@ -518,8 +518,8 @@
 
         'purchase_line_ids' : fields.one2many('training.course.purchase_line', 'course_id',
                                               'Supplier Commands',
-                                              help="The purchase line helps to create a purchase order for the seance",
-                                              read=['training.group_course_manager'], write=['training.group_course_manager']),
+                                              help="The purchase line helps to create a purchase order for the seance",),
+#                                              read=['training.group_course_manager'], write=['training.group_course_manager']),
 
 
         'has_support' : fields.function(_has_support,
@@ -3254,7 +3254,7 @@
         res = dict.fromkeys(ids, 0)
 
         for obj in self.browse(cr, uid, ids, context=context):
-            res[obj.id] = obj.session_id.available_seats - obj.session_id.draft_subscriptions
+            res[obj.id] = int(obj.session_id.available_seats) - int(obj.session_id.draft_subscriptions)
 
         return res
 

=== modified file 'training/training_view.xml'
--- training/training_view.xml	2011-03-14 10:48:46 +0000
+++ training/training_view.xml	2011-03-18 09:03:31 +0000
@@ -321,7 +321,7 @@
                         <field name="state_course" />
                         <button string="Deprecate" icon="terp-dialog-close" type="workflow" name="signal_deprecate" attrs="{'invisible' : [('state_course', '!=', 'validated')]}"
                             confirm="Do you want to deprecate this course ?" />
-                        <button string="Validate" icon="terp-accessories-archiver" type="workflow" name="signal_validate" attrs="{'invisible' : [('state_course', '!=', 'pending'),('state_course', '!=', 'draft')]}"
+                        <button string="Validate" icon="gtk-apply" type="workflow" name="signal_validate" attrs="{'invisible' : [('state_course', '!=', 'pending'),('state_course', '!=', 'draft')]}"
                             confirm="Do you want to validate this course ?" />
                         <button string="Reset to Draft" icon="terp-document-new" type="object" name="reset_to_draft" attrs="{'invisible' : [('state_course', '!=', 'deprecated')]}" />
                     </group>

=== modified file 'training/training_wizard.xml'
--- training/training_wizard.xml	2011-02-23 08:37:51 +0000
+++ training/training_wizard.xml	2011-03-18 09:03:31 +0000
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <openerp>
     <data>
+    <!--
         <wizard
             id="wizard_training_subscription_line_confirm"
             keyword="client_action_multi"
@@ -51,6 +52,6 @@
             name="training.subscription.session"
             groups="training.group_subscription_manager"
             string="Create Subscription"/>
-
+-->
     </data>
 </openerp>

=== modified file 'training/wizard/__init__.py'
--- training/wizard/__init__.py	2009-10-30 12:07:12 +0000
+++ training/wizard/__init__.py	2011-03-18 09:03:31 +0000
@@ -22,14 +22,15 @@
 
 import wizard_not_implemented
 import wizard_subscription_line_invoice
-import wizard_subscription_line_confirm
 import wizard_subscription_line_change_participant
+import wizard_spam
 import wizard_create_session
-import wizard_subscription_second_line
-import wizard_create_offer
-import wizard_create_block_offer
-import wizard_validate_course
-import wizard_spam
-import wizard_subscription_session
+import training_subscription_session
+import training_validate_course
+import training_subscription_line_confirm
+import training_create_offer
+import training_create_block_offer
+import training_subscription_second_line
+
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== renamed file 'training/wizard/wizard_create_block_offer.py' => 'training/wizard/training_create_block_offer.py'
--- training/wizard/wizard_create_block_offer.py	2009-10-28 13:24:27 +0000
+++ training/wizard/training_create_block_offer.py	2011-03-18 09:03:31 +0000
@@ -1,102 +1,89 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
-import pooler
+from osv import osv, fields
+from tools.translate import _
 import netsvc
-import tools
-from tools.translate import _
 
-class wizard_create_offers(wizard.interface):
-    first_screen_fields = {
-        'name' : {
-            'type' : 'char',
-            'size' : 64,
-            'string' : 'Name',
-            'required' : True,
-        },
-        'type_id' : {
-            'type' : 'many2one',
-            'relation' : 'training.course_type',
-            'string' : 'Type',
-            'required' : True,
-        },
-        'lang_id' : {
-            'type' : 'many2one',
-            'relation' : 'res.lang',
-            'string' : 'Language',
-            'required' : True,
-        }
+class training_create_block_offer(osv.osv_memory):
+    _name = 'training.create.block.offer'
+    _columns = {
+        'name' : fields.char('Name', size=64, required=True),
+        'type_id' : fields.many2one('training.course_type', 'Type', required=True,),
+        'lang_id' : fields.many2one('res.lang', 'Language', required=True,),
+        'product_line_id' : fields.many2one('training.course_category', 'Product Line', select=1, required=True),
     }
 
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Create a Block Offer" colspan="4">
-        <separator string="Offer Description" colspan="4"/>
-        <field name="name" />
-        <newline />
-        <field name="lang_id" />
-        <newline />
-        <field name="type_id" />
-    </form>'''
+    def default_get(self, cr, uid, fields, context=None):
+        if context is None:
+            context = {}
 
-    def init(self, cr, uid, data, context=None):
-        proxy = pooler.get_pool(cr.dbname).get(data['model'])
+        proxy = self.pool.get(context['active_model'])
         name = None
+        product_line = False
         languages = set()
-        for course in proxy.browse(cr, uid, data['ids'], context=context):
+
+        for course in proxy.browse(cr, uid, context.get('active_ids', []), context=context):
             if course.state_course != 'validated':
-                raise wizard.except_wizard(_('Warning'), _("Please, The state of all courses must be 'validated'"))
+                raise osv.except_osv(_('Warning'), _("Please, The state of all courses must be 'validated'"))
             if name is None:
                 name = course.name
+            product_line = course.category_id.id
             languages.add(course.lang_id.id)
 
         if len(languages) > 1:
-            raise wizard.except_wizard(_('Warning'), _('You have selected a course with a different language'))
-
-        return {'name' : name, 'lang_id' : list(languages)[0]}
-
-    def create_block_offer(self, cr, uid, data, context=None):
-        pool = pooler.get_pool(cr.dbname)
-
-        proxy_offer = pool.get('training.offer')
+            raise osv.except_osv(_('Warning'), _('You have selected a course with a different language'))
+
+        return {'name':name, 'lang_id':list(languages)[0], 'product_line_id':product_line, 'type_id':course.course_type_id.id}
+
+
+    def create_block_offer(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+
+        proxy_offer = self.pool.get('training.offer')
+        proxy_course_offer_rel = self.pool.get('training.course.offer.rel')
+
+        active_model = context.get('active_model', False)
+        if not active_model:
+            return {}
+
+        proxy_course = self.pool.get(active_model)
+        form = self.read(cr, uid, ids, [])[0]
         offer_id = proxy_offer.create(cr, uid,
                                       {
-                                          'name' : data['form']['name'],
-                                          'lang_id' : data['form']['lang_id'],
-                                          'type_id' : data['form']['type_id'],
+                                      'name' : form['name'],
+                                      'lang_id' : form['lang_id'],
+                                      'type_id' : form['type_id'],
+                                      'product_line_id': form['product_line_id'],
                                       },
                                       context=context)
 
-        proxy_course_offer_rel = pool.get('training.course.offer.rel')
-
-        proxy_course = pooler.get_pool(cr.dbname).get(data['model'])
-
-        for course in proxy_course.browse(cr, uid, data['ids'], context=context):
-            if course.lang_id.id != data['form']['lang_id']:
-                raise wizard.except_wizard(_('Warning'), _("Please, You have selected a course with a different language"))
-
-            proxy_course_offer_rel.create(cr, uid, { 'course_id' : course.id, 'offer_id' : offer_id, }, context=context)
-
-        proxy_offer.write(cr, uid, [offer_id], {'name' : data['form']['name']}, context=context)
+        for course in proxy_course.browse(cr, uid, context.get('active_ids',[]), context=context):
+            if course.lang_id.id != form['lang_id']:
+                raise osv.except_osv(_('Warning'), _("Please, You have selected a course with a different language"))
+
+            proxy_course_offer_rel.create(cr, uid, { 'course_id' : course.id, 'offer_id' : offer_id }, context=context)
+
+        proxy_offer.write(cr, uid, [offer_id], {'name' : form['name']}, context=context)
 
         return {
             'res_id' : int(offer_id),
@@ -108,26 +95,7 @@
             'type' : 'ir.actions.act_window',
         }
 
-    states = {
-        'init': {
-            'actions': [init],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('create_offers', 'Create the Block Offer', 'gtk-apply')],
-            }
-        },
-        'create_offers' : {
-            'result' : {
-                'type' : 'action',
-                'action' : create_block_offer,
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_create_offers('training.course.create.block.offer')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+
+training_create_block_offer()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== added file 'training/wizard/training_create_block_offer.xml'
--- training/wizard/training_create_block_offer.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/training_create_block_offer.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="training_create_block_offer_form">
+	        <field name="name">training.create.block.offer.form</field>
+	        <field name="model">training.create.block.offer</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Offer Description">
+	            	<group colspan="2" col="2">
+						<field name="name" />
+						<field name="type_id" />
+						<field name="lang_id" />
+						<field name="product_line_id" />
+					</group>
+	            	<newline/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="create_block_offer" string="Create Offers" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Create Block Offer"
+			    res_model="training.create.block.offer"
+			    src_model="training.course"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_training_create_block_offer"/>
+	</data>
+</openerp>

=== renamed file 'training/wizard/wizard_create_offer.py' => 'training/wizard/training_create_offer.py'
--- training/wizard/wizard_create_offer.py	2010-02-17 08:09:10 +0000
+++ training/wizard/training_create_offer.py	2011-03-18 09:03:31 +0000
@@ -1,69 +1,65 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
-import pooler
+from osv import osv, fields
+from tools.translate import _
 import netsvc
-import tools
-from tools.translate import _
-
-class wizard_create_offers(wizard.interface):
-    first_screen_fields = {
-    }
-
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Create Offers" colspan="6">
-        <label string="Do you want to create an offer for each selected course ?" />
-    </form>'''
-
-    def init(self, cr, uid, data, context=None):
-        if data['id']:
-            course = pooler.get_pool(cr.dbname).get(data['model']).browse(cr, uid, data['id'])
+
+class training_create_offer(osv.osv_memory):
+    _name = 'training.create.offer'
+
+    def default_get(self, cr, uid, fields, context=None):
+        if context is None:
+            context = {}
+
+        if context.get('active_id',False):
+            course = self.pool.get('training.course').browse(cr, uid, context['active_id'], context=context)
             if course.state_course != 'validated':
-                raise wizard.except_wizard(_('Warning'),_("Please, you can create an offer with a validated course"))
+                raise osv.except_osv(_('Warning'),_("Please, you can create an offer with a validated course"))
+
         return {}
 
-    def create_offers(self, cr, uid, data, context=None):
+    def create_offers(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+
         workflow = netsvc.LocalService('workflow')
-        pool = pooler.get_pool(cr.dbname)
-        proxy = pool.get('training.offer')
+        proxy = self.pool.get('training.offer')
         offer_ids = []
-        for course in pool.get('training.course').browse(cr, uid, data['ids'], context=context):
+        for course in self.pool.get('training.course').browse(cr, uid, context.get('active_ids',[]), context):
             if course.state_course == 'validated':
                 offer_id = proxy.create(cr, uid,
                                         {
-                                            'name' : course.name,
-                                            'lang_id' : course.lang_id.id,
-                                            'type_id' : course.course_type_id.id,
-                                            'product_line_id': course.category_id.id
+                                        'name' : course.name,
+                                        'lang_id' : course.lang_id.id,
+                                        'type_id' : course.course_type_id.id,
+                                        'product_line_id': course.category_id.id
                                         },
                                         context=context)
 
-                pool.get('training.course.offer.rel').create(cr, uid, {'offer_id' : offer_id, 'course_id' : course.id}, context=context)
+                self.pool.get('training.course.offer.rel').create(cr, uid, {'offer_id' : offer_id, 'course_id' : course.id}, context=context)
                 #workflow.trg_validate(uid, 'training.offer', offer_id, 'signal_validate', cr)
                 offer_ids.append(offer_id)
 
         number_of_offers = len(offer_ids)
-
         if not number_of_offers:
             return {}
         elif number_of_offers == 1:
@@ -87,26 +83,6 @@
                 'type' : 'ir.actions.act_window',
             }
 
-
-    states = {
-        'init': {
-            'actions': [init],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('create_offers', 'Create Offers', 'gtk-apply')],
-            }
-        },
-        'create_offers' : {
-            'result' : {
-                'type' : 'action',
-                'action' : create_offers,
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_create_offers('training.course.create.offer')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+training_create_offer()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== added file 'training/wizard/training_create_offer.xml'
--- training/wizard/training_create_offer.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/training_create_offer.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="training_create_offer_form">
+	        <field name="name">training.create.offer.form</field>
+	        <field name="model">training.create.offer</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Create Offers">
+	            	<label string="Do you want to create an offer for each selected course ?" />
+	            	<newline/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="create_offers" string="Create Offers" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Create Standalone Offer"
+			    res_model="training.create.offer"
+			    src_model="training.course"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_training_create_offer"/>
+	</data>
+</openerp>

=== renamed file 'training/wizard/wizard_subscription_line_confirm.py' => 'training/wizard/training_subscription_line_confirm.py'
--- training/wizard/wizard_subscription_line_confirm.py	2009-09-15 11:05:26 +0000
+++ training/wizard/training_subscription_line_confirm.py	2011-03-18 09:03:31 +0000
@@ -1,68 +1,39 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
+from osv import osv, fields
+from tools.translate import _
 import netsvc
-import ir
-import pooler
-
-confirm_form = """<?xml version="1.0"?>
-<form string="Confirm Subscription Lines">
-    <label string="Do you want to confirm all subscription lines ?" />
-</form>
-"""
-
-confirm_fields = {
-}
-
-def _confirm(self, cr, uid, data, context):
-    wf_service = netsvc.LocalService("workflow")
-
-    for obj_id in data['ids']:
-        wf_service.trg_validate(uid, 'training.subscription.line', obj_id, 'signal_confirm', cr)
-
-    return {}
-
-class line_confirm_them(wizard.interface):
-    states = {
-        'init' : {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': confirm_form,
-                'fields': confirm_fields,
-                'state': [
-                    ('end', 'Cancel', 'gtk-cancel'),
-                    ('confirm', 'Confirm', 'gtk-apply')
-                ]
-            }
-        },
-        'confirm' : {
-            'actions' : [_confirm],
-            'result' : {'type': 'state', 'state': 'end'}
-        },
-    }
-
-line_confirm_them("training.subscription.line.confirm")
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+
+class training_subscription_line_confim(osv.osv_memory):
+    _name = 'training.subscription.line.confim'
+
+    def confirm_line(self, cr, uid, ids, context=None):
+        if context is None:
+            context= {}
+        wf_service = netsvc.LocalService("workflow")
+        for obj_id in context.get('active_ids', []):
+            wf_service.trg_validate(uid, 'training.subscription.line', obj_id, 'signal_confirm', cr)
+        return {}
+
+training_subscription_line_confim()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== added file 'training/wizard/training_subscription_line_confirm.xml'
--- training/wizard/training_subscription_line_confirm.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/training_subscription_line_confirm.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="training_subscription_line_confim_form">
+	        <field name="name">training.subscription.line.confim.form</field>
+	        <field name="model">training.subscription.line.confim</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Confirm Subscription Lines">
+	            	<label string="Do you want to confirm all subscription lines ?" />
+	            	<newline/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="confirm_line" string="Confirm" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Confirm Subscription Lines"
+			    res_model="training.subscription.line.confim"
+			    src_model="training.subscription.line"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_training_subscription_line_confim"/>
+	</data>
+</openerp>

=== renamed file 'training/wizard/wizard_subscription_second_line.py' => 'training/wizard/training_subscription_second_line.py'
--- training/wizard/wizard_subscription_second_line.py	2009-08-03 20:22:23 +0000
+++ training/wizard/training_subscription_second_line.py	2011-03-18 09:03:31 +0000
@@ -1,47 +1,41 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
-import pooler
-import tools
-class wizard_subscription_second_line(wizard.interface):
-    first_screen_fields = { }
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Mass Subscription Second Line" colspan="6">
-       <label string="This wizard will generate the subscription !" />
-
-    </form>'''
-
-    def make_subscription(self, cr, uid, data, context=None):
-
-        subscription_line_second_ids = data['ids']
-
+from osv import osv, fields
+from tools.translate import _
+
+class training_subscription_second_line(osv.osv_memory):
+    _name = 'training.subscription.second.line'
+
+    def make_subscription(self, cr, uid, ids, context=None):
+        if context is None:
+            context={}
+
+        subscription_line_second_ids = context.get('active_ids',[])
         if not subscription_line_second_ids:
             return {}
 
-        pool=pooler.get_pool(cr.dbname)
-        sls_proxy = pool.get('training.subscription.line.second')
-        subscription_proxy= pool.get('training.subscription')
-        subscription_line_proxy = pool.get('training.subscription.line')
+        sls_proxy = self.pool.get('training.subscription.line.second')
+        subscription_proxy= self.pool.get('training.subscription')
+        subscription_line_proxy = self.pool.get('training.subscription.line')
 
         partners = {}
 
@@ -60,32 +54,16 @@
                 subscription_line_proxy.create(cr, uid, {'subscription_id' : subscription_id,
                                                          'session_id' : line.session_id.id,
                                                          'contact_id' : line.job_id.id,
+                                                         'price': 1.0,
+                                                         'job_id':line.job_id.id,
+                                                         'price_list_id':line.job_id.pricelist_id.id,
+                                                         'state': 'draft',
                                                         },
                                                context=context)
-
                 line.unlink()
 
         return {}
 
-    states = {
-        'init': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('make_subscription', 'Make Subscription', 'gtk-apply')],
-            }
-        },
-        'make_subscription' : {
-            'actions': [ make_subscription ],
-            'result' : {
-                'type' : 'state',
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_subscription_second_line('training.subscription.line_second')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+training_subscription_second_line()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== added file 'training/wizard/training_subscription_second_line.xml'
--- training/wizard/training_subscription_second_line.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/training_subscription_second_line.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="training_subscription_second_line_form">
+	        <field name="name">training.subscription.second.line.form</field>
+	        <field name="model">training.subscription.second.line</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Mass Subscription Second Line">
+	            	<label string="This wizard will generate the subscription !" />
+	            	<newline/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="make_subscription" string="Make Subscription" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Subscription Second Line"
+			    res_model="training.subscription.second.line"
+			    src_model="training.subscription.line.second"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_training_subscription_line_second"/>
+	</data>
+</openerp>

=== renamed file 'training/wizard/wizard_subscription_session.py' => 'training/wizard/training_subscription_session.py'
--- training/wizard/wizard_subscription_session.py	2009-09-07 13:05:53 +0000
+++ training/wizard/training_subscription_session.py	2011-03-18 09:03:31 +0000
@@ -1,124 +1,72 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
-import pooler
-import tools
+from osv import osv, fields
+from tools.translate import _
 
-class wizard_subscription_session(wizard.interface):
-    first_screen_fields = {
-        'partner_id' : {
-            'string' : 'Partner',
-            'type' : 'many2one',
-            'relation' : 'res.partner',
-            'required' : True,
-        },
-        'job_ids' : {
-            'string' : 'Contacts',
-            'type' : 'many2many',
-            'relation' : 'res.partner.job',
-            'domain' : "[('name', '=', partner_id),('state', '=', 'current')]",
-        },
-        'line_ids' : {
-            'string' : 'Sessions',
-            'type' : 'many2many',
-            'relation' : 'training.session',
-            'domain':"[('state', 'in', ('opened','opened_confirmed'))]"
-        }
+class training_subscription_session(osv.osv_memory):
+    _name = 'training.subscription.session'
+    _columns = {
+        'partner_id': fields.many2one('res.partner', 'Partner',  required=True),
+        'job_ids': fields.many2many('res.partner.job', 'res_partner_job_rel', 'training_id', 'partner_id', 'Contacts'),
+        'line_ids': fields.many2many('training.session', 'training_session_rel', 'training_id', 'session_id', 'Sessions'),
     }
 
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Mass Subscription" colspan="6">
-        <separator string="Partner" colspan="4" />
-        <field name="partner_id" colspan="4" />
-        <separator string="Contacts" colspan="4" />
-        <field name="job_ids" nolabel="1" colspan="4" />
-        <separator string="Sessions" colspan="2" />
-        <field name="line_ids" nolabel="1" colspan="4" />
-    </form>'''
-
-
-    def make_subscription(self, cr, uid, data, context=None):
-        pool = pooler.get_pool(cr.dbname)
-
-        subscription_proxy = pool.get('training.subscription')
-        subscription_line_proxy = pool.get('training.subscription.line')
-        partner_id=data['form']['partner_id']
+    def make_subscription(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+
+        form = self.read(cr, uid, ids, [])[0]
+        subscription_proxy = self.pool.get('training.subscription')
+        subscription_line_proxy = self.pool.get('training.subscription.line')
+        partner_obj = self.pool.get('res.partner')
+        partner_id = form['partner_id']
         values = subscription_proxy.on_change_partner(cr, uid, [], partner_id)['value']
         values.update({
                 'partner_id' : partner_id,
             })
-
         subscription_id = subscription_proxy.create(cr, uid, values, context=context)
-
-        partner = pool.get('res.partner').browse(cr, uid, data['form']['partner_id'], context=context)
+        partner = partner_obj.browse(cr, uid, form['partner_id'], context=context)
         def_pricelist_id = partner.property_product_pricelist.id
 
-        masslines = pool.get('training.subscription.mass.line')
-        if data['form']['job_ids']:
-            for job_id in data['form']['job_ids'][0][2]:
-                for line in data['form']['line_ids']:
-                    mlid = line[2]
-                    if not isinstance(mlid, (int, long)):
-                        for i in line[2]:
-                            val={'session_id':i}
-                            mlid = masslines.create(cr, uid, val)
-                            massline = masslines.browse(cr, uid, mlid, context=context)
-                            job = pool.get('res.partner.job').browse(cr, uid, job_id, context=context)
-                            values = subscription_line_proxy._get_values_from_wizard(cr, uid, subscription_id, job, massline, context=context)
-
-                            sl_id = subscription_line_proxy.create(cr, uid, values, context=context)
-
+        masslines = self.pool.get('training.subscription.mass.line')
+        if form['job_ids']:
+            for job_id in form['job_ids']:
+                for line in form['line_ids']:
+                    val={'session_id':line}
+                    mlid = masslines.create(cr, uid, val)
+                    massline = masslines.browse(cr, uid, mlid, context=context)
+                    job = self.pool.get('res.partner.job').browse(cr, uid, job_id, context=context)
+                    values = subscription_line_proxy._get_values_from_wizard(cr, uid, subscription_id, job, massline, context=context)
+                    sl_id = subscription_line_proxy.create(cr, uid, values, context=context)
         return {
-
             'view_type': 'form',
             "view_mode": 'form',
             'res_model': 'training.subscription',
-            'view_id': pool.get('ir.ui.view').search(cr,uid,[('name','=','training.subscription.form')]),
+            'view_id': self.pool.get('ir.ui.view').search(cr,uid,[('name','=','training.subscription.form')]),
             'type': 'ir.actions.act_window',
             'target': 'current',
             'res_id' : int(subscription_id)
         }
 
-
-    states = {
-        'init': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('make_subscription', 'Make Subscription', 'gtk-apply')],
-            }
-        },
-        'make_subscription' : {
-            'result' : {
-                'type' : 'action',
-                'action' : make_subscription,
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_subscription_session('training.subscription.session')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+training_subscription_session()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== added file 'training/wizard/training_subscription_session.xml'
--- training/wizard/training_subscription_session.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/training_subscription_session.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="training_subscription_session_form">
+	        <field name="name">training.subscription.session.form</field>
+	        <field name="model">training.subscription.session</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Mass Subscription">
+	            	<separator string="Partner" colspan="4"/>
+	                <field name="partner_id" nolabel="1"  colspan="4" />
+	                <separator string="Contacts" colspan="4" />
+	                <field name="job_ids"  nolabel="1" colspan="4" domain="[('name', '=', partner_id),('state', '=', 'current')]" />
+	                <separator string="Sessions" colspan="2" />
+	                <field name="line_ids" nolabel="1" colspan="4" domain="[('state', 'in', ('opened','opened_confirmed'))]"/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="make_subscription" string="Create Subscription" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Create Subscriptions"
+			    res_model="training.subscription.session"
+			    src_model="training.session"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_training_subscription_session"/>
+	</data>
+</openerp>

=== renamed file 'training/wizard/wizard_validate_course.py' => 'training/wizard/training_validate_course.py'
--- training/wizard/wizard_validate_course.py	2009-08-13 05:51:39 +0000
+++ training/wizard/training_validate_course.py	2011-03-18 09:03:31 +0000
@@ -20,49 +20,22 @@
 #
 ##############################################################################
 
-import wizard
-import pooler
-import tools
 import netsvc
-
-class wizard_validate_courses(wizard.interface):
-    first_screen_fields = {
-    }
-
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Create Offers" colspan="6">
-        <label string="Do you want to validate the selected courses ?" />
-    </form>'''
-
-    def validate_courses(self, cr, uid, data, context=None):
+from osv import osv, fields
+
+class validate_courses(osv.osv_memory):
+    _name = 'validate.courses'
+
+    def validate_courses(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         workflow = netsvc.LocalService('workflow')
-        pool = pooler.get_pool(cr.dbname)
-        proxy = pool.get('training.course')
-        for course in proxy.browse(cr, uid, data['ids'], context=context):
+        proxy = self.pool.get('training.course')
+        for course in proxy.browse(cr, uid, context.get('active_ids',[]), context=context):
             if course.state_course in ('pending','draft'):
                 workflow.trg_validate(uid, 'training.course', course.id, 'signal_validate', cr)
-
         return {}
 
-    states = {
-        'init': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('validate_courses', 'Validate Courses', 'gtk-apply')],
-            }
-        },
-        'validate_courses' : {
-            'result' : {
-                'type' : 'action',
-                'action' : validate_courses,
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_validate_courses('training.course.validate')
+validate_courses()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'training/wizard/validate_course_view.xml'
--- training/wizard/validate_course_view.xml	1970-01-01 00:00:00 +0000
+++ training/wizard/validate_course_view.xml	2011-03-18 09:03:31 +0000
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+	<data>
+	    <record model="ir.ui.view" id="validate_courses_form">
+	        <field name="name">validate.courses.form</field>
+	        <field name="model">validate.courses</field>
+	        <field name="type">form</field>
+	        <field name="arch" type="xml">
+	            <form string="Validate Courses">
+	            	<label string="Do you want to validate the selected courses ?" />
+	            	<newline/>
+	                <group colspan="2" col="2">
+	                    <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+	                    <button type="object" name="validate_courses" string="Validate Courses" icon="gtk-apply"/>
+	                </group>
+	            </form>
+	        </field>
+	    </record>
+
+	    <act_window name="Validate Course(s)"
+			    res_model="validate.courses"
+			    src_model="training.course"
+			    view_mode="form"
+			    target="new"
+	            key2="client_action_multi"
+			    id="action_validate_courses"/>
+	</data>
+</openerp>

=== renamed file 'training_degree/__terp__.py' => 'training_degree/__openerp__.py'
--- training_degree/__terp__.py	2011-02-25 12:33:02 +0000
+++ training_degree/__openerp__.py	2011-03-18 09:03:31 +0000
@@ -8,8 +8,9 @@
     'update_xml' : [
         'security/training_degree_security.xml',
         'security/ir.model.access.csv',
+        'wizard/training_validate_degree.xml',
         'training_degree_view.xml',
-	'training_degree_wizard.xml',
+	    'training_degree_wizard.xml',
     ],
     'init_xml' : [],
     'demo_xml' : [],

=== modified file 'training_degree/training_degree.py'
--- training_degree/training_degree.py	2011-02-15 10:30:41 +0000
+++ training_degree/training_degree.py	2011-03-18 09:03:31 +0000
@@ -1,3 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
 from osv import osv, orm, fields
 
 import tools
@@ -20,13 +41,16 @@
     _inherit = 'training.course'
 
     def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
+        if context is None:
+            context = {}
+
         has_validated_questionnaire = context and context.get('has_validated_questionnaire', False) or False
         has_lang_id = context and context.get('has_lang_id', False) or False
 
         if has_validated_questionnaire and has_lang_id:
             cr.execute("SELECT course.id "
                        "FROM training_course course "
-                       "WHERE EXISTS ( SELECT * FROM training_exam_questionnaire WHERE course_id = course.id) "
+                       "WHERE EXISTS ( SELECT * FROM training_exam_questionnaire WHERE main_course_id = course.id) "
                        "  AND course.lang_id = %s", (has_lang_id,))
             course_ids = [x[0] for x in cr.fetchall()]
 
@@ -70,15 +94,23 @@
     }
 
     def action_deprecate(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         return self.write(cr, uid, ids, {'state' : 'deprecated'}, context=context)
 
     def action_validate(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         return self.write(cr, uid, ids, {'state' : 'validated'}, context=context)
 
     def action_draft(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         return self.write(cr, uid, ids, {'state' : 'draft'}, context=context)
 
     def _lang_default(self, cr, uid, context=None):
+        if context is None:
+            context = {}
         lang_proxy = self.pool.get('res.lang')
         user_proxy = self.pool.get('res.users')
 
@@ -95,10 +127,8 @@
 
 class training_degree_contact(osv.osv):
     _name = 'training.degree.contact'
-
     _rec_name = 'degree_id'
 
-
     def _get_courses_status(self, cr, uid, ids, fieldnames, args, context=None):
         if not context:
             context = {}
@@ -138,7 +168,7 @@
             res[degree.id] = {
                 'courses_todo_ids': [ c for c, s in dc_status.iteritems() if not s ],
                 'courses_done_ids': [ c for c, s in dc_status.iteritems() if s],
-                'courses_history': dc_history,
+                'courses_history': list(dc_history),
             }
         return res
 
@@ -260,6 +290,9 @@
     }
 
     def action_acquire(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+
         return self.write(cr, uid, ids, {'state' : 'acquired', 'date' : time.strftime("%Y-%m-%d")}, context=context)
 
 training_degree_contact()
@@ -269,7 +302,10 @@
 
 
     def search(self, cr, uid, domain, offset = 0, limit = None, order = None, context = None, count = False):
-        eligible_degree = context and context.get('eligible_degree', False) or False
+        if context is None:
+            context = {}
+
+        eligible_degree = context.get('eligible_degree', False) or False
 
         if eligible_degree:
             proxy = self.pool.get('training.degree.contact')
@@ -371,6 +407,8 @@
         return { 'value' : { key : 0 }}
 
     def show_degrees_cb(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         dc_proxy = self.pool.get('training.degree.contact.view')
         wl_proxy = self.pool.get('training.degree.contact.wiz.line')
         dg_proxy = self.pool.get('training.degree')
@@ -416,6 +454,8 @@
         return self.write(cr, uid, ids, {'state' : 'show_degrees'}, context=context)
 
     def select_all_cb(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         for obj in self.browse(cr, uid, ids, context=context):
             for line in obj.line_ids:
                 line.write({'subscribe' : 1})
@@ -423,6 +463,8 @@
         return True
 
     def deselect_all_cb(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         for obj in self.browse(cr, uid, ids, context=context):
             for line in obj.line_ids:
                 line.write({'subscribe' : 0})
@@ -430,6 +472,8 @@
         return True
 
     def subscribe_cb(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         proxy = self.pool.get('training.degree.contact')
         dc_ids = []
         for obj in self.browse(cr, uid, ids, context=context):
@@ -497,10 +541,12 @@
 
     _defaults = {
         'state' : lambda *a: 'init',
-        'degree_id': lambda *a: None,
+        'degree_id': lambda *a: False,
     }
 
     def get_contact_email_address(self, cr, uid, contact_id, context=None):
+        if context is None:
+            context = {}
         contact = self.pool.get('res.partner.contact').browse(cr, uid, contact_id, context=context)
         jobs = self.pool.get('res.partner.job')
         if contact.email:
@@ -543,6 +589,8 @@
         return ''
 
     def generate_reports_cb(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
         proxy = self.pool.get('training.degree.contact')
         jobs_proxy = self.pool.get('res.partner.job')
         participation_proxy = self.pool.get('training.participation')
@@ -586,23 +634,24 @@
                     dc_ids = proxy.search(cr, uid, [('degree_id', '=', degree.id)], context=context)
 
                     dc_full_stats = {}
-                    cr.execute("""
-                        SELECT
-                            contact_id,
-                            participation_id,
-                            course_id,
-                            succeeded
-                        FROM
-                            training_exam_contact_results_stat
-                        WHERE
-                            course_id IN %s
-                        AND
-                            contact_id IN (
-                                SELECT contact_id
-                                FROM training_degree_contact
-                                WHERE degree_id = %s
-                            )
-                        """, (ids_of_courses, degree.id))
+                    if ids_of_courses:
+                        cr.execute("""
+                            SELECT
+                                contact_id,
+                                participation_id,
+                                course_id,
+                                succeeded
+                            FROM
+                                training_exam_contact_results_stat
+                            WHERE
+                                course_id IN %s
+                            AND
+                                contact_id IN (
+                                    SELECT contact_id
+                                    FROM training_degree_contact
+                                    WHERE degree_id = %s
+                                )
+                            """, (ids_of_courses, degree.id,))
                     dc_results = cr.dictfetchall()
                     for result in dc_results:
                         c = result['contact_id']

=== modified file 'training_degree/training_degree_view.xml'
--- training_degree/training_degree_view.xml	2011-02-15 10:30:41 +0000
+++ training_degree/training_degree_view.xml	2011-03-18 09:03:31 +0000
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <openerp>
-
     <data>
+
         <record model="ir.ui.view" id="degree_form">
             <field name="name">training.degree.form</field>
             <field name="model">training.degree</field>
@@ -12,7 +12,7 @@
                     <field name="name" attrs="{'readonly' : [('state', 'in', ('deprecated', 'validated'))]}" />
                     <field name="lang_id" attrs="{'readonly' : [('state', 'in', ('deprecated', 'validated'))]}"/>
                     <separator string="Courses" colspan="4" />
-                    <field colspan="4" nolabel="1" name="course_ids" 
+                    <field colspan="4" nolabel="1" name="course_ids"
                         context="{'has_validated_questionnaire':True, 'has_lang_id' : lang_id}"
                         attrs="{'readonly' : [('state', 'in', ('deprecated', 'validated'))]}">
                         <tree string="Courses">
@@ -23,9 +23,9 @@
                     </field>
                     <group colspan="4" col="5">
                         <field name="state" />
-                        <button name="action_validate" string="Validate" type="object" states="draft" />
-                        <button name="action_deprecate" string="Deprecate" type="object" states="validated" />
-                        <button name="action_draft" string="Reset to Draft" type="object" states="deprecated" />
+                        <button name="action_validate" string="Validate" type="object" states="draft" icon="gtk-apply"/>
+                        <button name="action_deprecate" string="Deprecate" type="object" states="validated" icon="terp-dialog-close"/>
+                        <button name="action_draft" string="Reset to Draft" type="object" states="deprecated" icon="gtk-convert"/>
                     </group>
                 </form>
             </field>
@@ -44,42 +44,43 @@
             </field>
         </record>
 
+        <record id="training_degree_filter" model="ir.ui.view">
+            <field name="name">Degree Search</field>
+            <field name="model">training.degree</field>
+            <field name="type">search</field>
+            <field name="priority">1</field>
+            <field name="arch" type="xml">
+                <search string="Search Degree">
+                	<filter icon="terp-document-new" string="Draft" domain="[('state', '=', 'draft')]" />
+                	<filter icon="terp-check" string="Validate" domain="[('state', '=', 'validated')]" />
+                	<filter icon="gtk-close" string="Deprecated" domain="[('state', '=', 'deprecated')]" />
+                    <separator orientation="vertical"/>
+                    <field name="name" />
+                    <field name="lang_id" />
+                    <field name="state"/>
+                    <newline/>
+                    <group expand="0" string="Group By...">
+                        <filter string="Lang" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'lang_id'}"/>
+                        <separator orientation="vertical"/>
+                        <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+                    </group>
+                </search>
+            </field>
+        </record>
+
         <record model="ir.actions.act_window" id="degree_all_act">
             <field name="name">Degrees</field>
             <field name="res_model">training.degree</field>
             <field name="view_type">form</field>
             <field name="view_mode">tree,form</field>
-        </record>
-
-        <record model="ir.actions.act_window" id="degree_draft_act">
-            <field name="name">Draft Degrees</field>
-            <field name="res_model">training.degree</field>
-            <field name="view_type">form</field>
-            <field name="view_mode">tree,form</field>
-            <field name="domain">[('state', '=', 'draft')]</field>
-        </record>
-
-        <record model="ir.actions.act_window" id="degree_validated_act">
-            <field name="name">Validated Degrees</field>
-            <field name="res_model">training.degree</field>
-            <field name="view_type">form</field>
-            <field name="view_mode">tree,form</field>
-            <field name="domain">[('state', '=', 'validated')]</field>
-        </record>
-
-        <record model="ir.actions.act_window" id="degree_new_act">
-            <field name="name">New Degree</field>
-            <field name="res_model">training.degree</field>
-            <field name="view_type">form</field>
-            <field name="view_mode">form</field>
+            <field name="search_view_id" ref="training_degree_filter"/>
         </record>
 
         <menuitem parent="training.training_library_mi" id="degree_mi" name="Degrees" />
 
         <menuitem parent="degree_mi" id="degree_all_mi" action="degree_all_act" />
-        <menuitem parent="degree_all_mi" id="degree_draft_mi" action="degree_draft_act" />
-        <menuitem parent="degree_all_mi" id="degree_new_mi" action="degree_new_act" />
-        <menuitem parent="degree_all_mi" id="degree_validate_mi" action="degree_validated_act" />
+
+		<menuitem parent="training.training_mi" id="degree_contact_mi" name="Degrees Contact" />
 
         <record model="ir.ui.view" id="degree_contact_form">
             <field name="name">training.degree.contact.form</field>
@@ -120,7 +121,7 @@
                         <field name="state_summary" />
                         <field name="state" invisible="1"/>
                         <group colspan="1" attrs="{'invisible':[('state_summary', '==', 'desired')]}">
-                            <button name="action_acquire" type="object" string="Acquire" states="desired" groups="training_degree.group_degree_manager" />
+                            <button name="action_acquire" type="object" string="Acquire" states="desired" groups="training_degree.group_degree_manager" icon="gtk-apply"/>
                         </group>
                     </group>
 
@@ -144,14 +145,42 @@
             </field>
         </record>
 
+        <record id="training_contact_degree_filter" model="ir.ui.view">
+            <field name="name">Degree Search</field>
+            <field name="model">training.degree.contact</field>
+            <field name="type">search</field>
+            <field name="priority">1</field>
+            <field name="arch" type="xml">
+                <search string="Search Degrees">
+                	<filter icon="terp-tools" string="Desired" domain="[('state_summary', '=', 'desired')]" />
+                	<filter icon="terp-check" string="Eligible" domain="[('state_summary', '=', 'eligible')]" />
+                	<filter icon="gtk-apply" string="Acquired" domain="[('state_summary', '=', 'acquired')]" />
+                    <separator orientation="vertical"/>
+                    <field name="degree_id"/>
+                    <field name="contact_id" />
+                    <field name="state_summary"/>
+                    <newline/>
+                    <group expand="0" string="Group By...">
+                        <filter string="Degree" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'degree_id'}"/>
+                        <filter string="Contact" icon="terp-personal" domain="[]" context="{'group_by':'contact_id'}"/>
+                        <separator orientation="vertical"/>
+                        <filter string="Date Obtained" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
+                        <separator orientation="vertical"/>
+                        <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state_summary'}"/>
+                    </group>
+                </search>
+            </field>
+        </record>
+
         <record model="ir.actions.act_window" id="degree_contact_act">
             <field name="name">Degrees</field>
             <field name="res_model">training.degree.contact</field>
             <field name="view_type">form</field>
             <field name="view_mode">tree,form</field>
+            <field name="search_view_id" ref="training_contact_degree_filter"/>
         </record>
 
-        <menuitem action="degree_contact_act" parent="training.training_mi" id="degree_contact_all_mi" />
+        <menuitem action="degree_contact_act" parent="degree_contact_mi" id="degree_contact_all_mi" />
 
         <act_window id="acquired_degree_contact"
             name="Acquired Degrees"
@@ -206,8 +235,8 @@
                         <field name="state" />
                         <button name="cancel_cb" special="cancel" type="object" string="Cancel" icon="gtk-cancel" />
                         <button name="show_degrees_cb" type="object" string="Show Degrees" icon="gtk-apply" />
-                        <button name="subscribe_cb" type="object" string="Subscribe to Degrees" icon="gtk-execute" states="show_degrees" />
-                        <button name="close_cb" type="object" string="Close" icon="gtk-close" states="show_degrees" />
+                        <button name="subscribe_cb" type="object" string="Subscribe to Degrees" states="show_degrees" icon="gtk-execute"/>
+                        <button name="close_cb" type="object" string="Close" states="show_degrees" icon="gtk-close"/>
                     </group>
                 </form>
             </field>
@@ -221,7 +250,7 @@
             <field name="target">new</field>
         </record>
 
-        <menuitem id="degree_contact_wizard_mi" parent="degree_contact_all_mi" action="degree_contact_wizard_act"/>
+        <menuitem id="degree_contact_wizard_mi" parent="degree_contact_mi" action="degree_contact_wizard_act"/>
 
         <record model="ir.ui.view" id="training_degree_contact_report_form">
             <field name="name">training.degree.contact.report.form</field>
@@ -240,9 +269,9 @@
                     <separator colspan="4" />
                     <group col="5" colspan="4">
                         <field name="state" invisible="1" />
-                        <button name="close_cb" string="Cancel" type="object" icon="gtk-cancel" states="init" />
-                        <button name="generate_reports_cb" string="Generate Reports" type="object" icon="gtk-apply" states="init" />
-                        <button name="close_cb" string="Close" type="object" icon="gtk-close" states="generate_reports" />
+                        <button name="close_cb" string="Cancel" type="object" states="init" icon="gtk-cancel" />
+                        <button name="generate_reports_cb" string="Generate Reports" type="object" states="init" icon="gtk-apply" />
+                        <button name="close_cb" string="Close" type="object" states="generate_reports" icon="gtk-close"/>
                     </group>
                 </form>
             </field>
@@ -256,6 +285,6 @@
             <field name="target">new</field>
         </record>
 
-        <menuitem id="degree_contact_report_mi" parent="degree_contact_all_mi" action="training_degree_contact_report_act"/>
+        <menuitem id="degree_contact_report_mi" parent="degree_contact_mi" action="training_degree_contact_report_act"/>
     </data>
 </openerp>

=== modified file 'training_degree/training_degree_wizard.xml'
--- training_degree/training_degree_wizard.xml	2010-01-25 15:53:09 +0000
+++ training_degree/training_degree_wizard.xml	2011-03-18 09:03:31 +0000
@@ -20,13 +20,5 @@
             string="Compute Eligible Degrees"/>
         -->
 
-        <wizard
-            id="wizard_training_degree_validate_all"
-            keyword="client_action_multi"
-            model="training.degree.contact"
-            name="training.degree.validate.all"
-            multi="True"
-            groups="training_degree.group_degree_manager" 
-            string="Validate Assigned Degrees"/>
     </data>
 </openerp>

=== modified file 'training_degree/wizard/__init__.py'
--- training_degree/wizard/__init__.py	2009-11-09 14:17:06 +0000
+++ training_degree/wizard/__init__.py	2011-03-18 09:03:31 +0000
@@ -23,7 +23,7 @@
 
 import wizard_eligible_contacts
 import wizard_contacts_are_eligible_to_degrees
-import wizard_validate_degrees
+import training_validate_degree
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 

=== renamed file 'training_degree/wizard/wizard_validate_degrees.py' => 'training_degree/wizard/training_validate_degree.py'
--- training_degree/wizard/wizard_validate_degrees.py	2009-11-09 14:17:06 +0000
+++ training_degree/wizard/training_validate_degree.py	2011-03-18 09:03:31 +0000
@@ -1,68 +1,40 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
-import wizard
-import pooler
-import tools
+from osv import osv, fields
 from tools.translate import _
-
-class wizard_validate_degrees(wizard.interface):
-    first_screen_fields = {
-    }
-
-    first_screen_form = '''<?xml version="1.0"?>
-    <form string="Eligible Contacts">
-        <label string="Do you want to confirm all selected degrees ?" />
-    </form>'''
-
-    def validate_all_degrees(self, cr, uid, data, context=None):
-
-        proxy = pooler.get_pool(cr.dbname).get('training.degree.contact')
-
-        for obj in proxy.browse(cr, uid, data['ids'], context=context):
+import netsvc
+
+class validate_degree(osv.osv_memory):
+    _name = 'validate.degree'
+
+    def validate_all_degrees(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        proxy = self.pool.get('training.degree.contact')
+        for obj in proxy.browse(cr, uid, context.get('active_ids',[]), context=context):
             if obj.state == 'desired' and obj.is_eligible == 'yes':
                 obj.action_acquire()
-
         return {}
 
-    states = {
-        'init': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': first_screen_form,
-                'fields': first_screen_fields,
-                'state':[('end','Cancel', 'gtk-cancel'),('validate', 'Validate Assigned Degrees', 'gtk-execute')],
-            }
-        },
-        'validate' : {
-            'result' : {
-                'type' : 'action',
-                'action' : validate_all_degrees,
-                'state' : 'end',
-            }
-        }
-    }
-
-wizard_validate_degrees('training.degree.validate.all')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+validate_degree()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file


Follow ups