← Back to team overview

openerp-dev-web team mailing list archive

[Merge] lp:~openerp-dev/openobject-addons/addons-training-report-ysa into lp:~openobject-training/openobject-addons/training_with_history

 

Yogesh(Open ERP) has proposed merging lp:~openerp-dev/openobject-addons/addons-training-report-ysa 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/addons-training-report-ysa/+merge/53779

training_report:- convert v5 to v6 and fix problem.
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/addons-training-report-ysa/+merge/53779
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-addons/addons-training-report-ysa.
=== modified file 'training_report/__init__.py'
--- training_report/__init__.py	2009-08-24 08:58:54 +0000
+++ training_report/__init__.py	2011-03-17 10:37:29 +0000
@@ -23,5 +23,5 @@
 import training_report
 import report
 import wizard
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-

=== renamed file 'training_report/__terp__.py' => 'training_report/__openerp__.py'
--- training_report/__terp__.py	2011-02-25 12:33:02 +0000
+++ training_report/__openerp__.py	2011-03-17 10:37:29 +0000
@@ -20,7 +20,6 @@
 #
 ##############################################################################
 
-
 {
     'name': 'Training Management - Reporting',
     'version': '1.0',
@@ -36,6 +35,7 @@
     'depends': [
         'training',
         'training_intra',
+        'training_exam',
     ],
     'init_xml': [],
     'update_xml': [
@@ -43,9 +43,13 @@
         'security/ir.model.access.csv',
         'report_training_view.xml',
         'training_report.xml',
+        'wizard/training_report_account_analytic_balance_year_view.xml',
+        'wizard/training_report_course_profitability_view.xml',
+        'wizard/training_report_session_volume_view.xml',
     ],
     'demo_xml': [],
     'installable': True,
     'active': False,
 }
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'training_report/report/analytic_balance_year.py'
--- training_report/report/analytic_balance_year.py	2009-11-25 16:36:08 +0000
+++ training_report/report/analytic_balance_year.py	2011-03-17 10:37:29 +0000
@@ -20,10 +20,8 @@
 #
 ##############################################################################
 
-import pooler
 import time
 from report import report_sxw
-import datetime
 
 class account_analytic_balance_year(report_sxw.rml_parse):
     def __init__(self, cr, uid, name, context):
@@ -43,12 +41,9 @@
         })
 
     def _lines_g(self, account_id, date1, date2):
-        year=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
         account_analytic_obj = self.pool.get('account.analytic.account')
-        ids = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', [account_id])])
+        year = [int(date1[0:4]) - 1, int(date1[0:4])]
+        ids = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', [account_id])])
         self.cr.execute("SELECT aa.name AS name, aa.code AS code, \
                     sum(aal.amount) AS balance, sum(aal.unit_amount) AS quantity \
                 FROM account_analytic_line AS aal, account_account AS aa \
@@ -58,49 +53,46 @@
                     And date_part('year',date) in ("+ ','.join(map(str, year)) +") \
                 GROUP BY aal.general_account_id, aa.name, aa.code, aal.code ,date_part('year',date)\
                 ORDER BY aal.code", (date1[5:10], date2[5:10]))
-        res = self.cr.dictfetchall()
+        result = self.cr.dictfetchall()
 
-        for r in res:
-            if r['balance'] > 0:
-                r['debit'] = r['balance']
-                r['credit'] = 0.0
-            elif r['balance'] < 0:
-                r['debit'] = 0.0
-                r['credit'] = -r['balance']
+        for res in result:
+            if res.get('balance') > 0:
+                res.update({
+                    'debit' : res.get('balance',0),
+                    'credit' : 0.0
+                })
+            elif res.get('balance') < 0:
+                res.update({
+                    'debit' : 0.0,
+                    'credit' : -res.get('balance',0)
+                })
             else:
-                r['balance'] == 0
-                r['debit'] = 0.0
-                r['credit'] = 0.0
-        return res
+                res.update({
+                    'balance' : 0.0,
+                    'debit' : 0.0,
+                    'credit' : -res.get('balance',0)
+                })
+        return result
 
     def _get_year(self,date1,date2):
-        year=[]
-        year.append(str(int(date1[0:4])-1))
-        year.append(str(int(date1[0:4])))
-        return year
+        return [str(int(date1[0:4])-1), str(int(date1[0:4]))]
+
     def _get_data(self, account_id, date1, date2):
-        res=[]
-        r={}
-        year=[]
-        year.append(str(int(date1[0:4])-1))
-        year.append(str(int(date1[0:4])))
+        year = [str(int(date1[0:4])-1), str(int(date1[0:4]))]
         debit = self._move_sum_debit(account_id, date1, date2)
         credit = self._move_sum_credit(account_id, date1, date2)
-        amount=self._move_sum_balance(account_id, date1, date2)
-        r['debit']=debit
-        r['credit']=credit
-        r['amount']=amount
-        r['year']=year
-        return r
+        amount = self._move_sum_balance(account_id, date1, date2)
+        return {
+                'debit' : debit,
+                'credit' : credit,
+                'amount' : amount,
+                'year' : year
+                }
 
     def _move_sum_debit(self, account_id, date1, date2):
-        res=[]
-        year=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
         account_analytic_obj = self.pool.get('account.analytic.account')
-        ids = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', [account_id])])
+        year [int(date1[0:4])-1, int(date1[0:4])]
+        ids = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', [account_id])])
         self.cr.execute("SELECT sum(amount)\
             FROM account_analytic_line \
             WHERE account_id in ("+ ','.join(map(str, ids)) +") \
@@ -108,66 +100,49 @@
                 and date_part('year',date) in ("+ ','.join(map(str, year)) +") \
                 group by date_part('year',date)",(date1[5:10], date2[5:10]))
 
-        res =self.cr.dictfetchall()
-        return res
+        return self.cr.dictfetchall()
 
     def _move_sum_credit(self, account_id, date1, date2):
-        year=[]
-        res=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
         account_analytic_obj = self.pool.get('account.analytic.account')
-        ids = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', [account_id])])
+        year = [int(date1[0:4])-1, int(date1[0:4])]
+        ids = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', [account_id])])
         self.cr.execute("SELECT -sum(amount) as sum \
             FROM account_analytic_line \
             WHERE account_id in ("+ ','.join(map(str, ids)) +") \
              AND to_char(date, 'MM-DD')>=%s AND to_char(date, 'MM-DD')<=%s AND amount>0 \
                 and date_part('year',date) in ("+ ','.join(map(str, year)) +") \
                 group by date_part('year',date)",(date1[5:10], date2[5:10]))
-        res= self.cr.dictfetchall()
-        return res
+        return self.cr.dictfetchall()
 
     def _move_sum_balance(self, account_id, date1, date2):
-        res=[]
-        account_analytic_obj = self.pool.get('account.analytic.account')
-        ids = account_analytic_obj.search(self.cr, self.uid,
-        [('parent_id', 'child_of', [account_id])])
+        result = []
         debit = self._move_sum_debit(account_id, date1, date2)
-        temp =len(debit)
         credit = self._move_sum_credit(account_id, date1, date2)
-        for i in range(temp):
-            res.append(debit[i]['sum']-credit[i]['sum'])
-        return res
+        for index in range(len(debit)):
+            result.append(debit[index]['sum'] - credit[index]['sum'])
+        return result
 
     def _move_sum_quantity(self, account_id, date1, date2):
-        year=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
         account_analytic_obj = self.pool.get('account.analytic.account')
-        ids = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', [account_id])])
+        year = [int(date1[0:4])-1, int(date1[0:4])]
+        ids = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', [account_id])])
         self.cr.execute("SELECT sum(unit_amount) as sum,date_part('year',date) as year \
                 FROM account_analytic_line \
                 WHERE account_id in ("+ ','.join(map(str, ids)) +") \
                     AND to_char(date, 'MM-DD')>=%s AND to_char(date, 'MM-DD')<=%s AND amount<0 \
                     and date_part('year',date) in ("+ ','.join(map(str, year)) +") \
                     group by date_part('year',date)",(date1[5:10], date2[5:10]))
+
         return self.cr.dictfetchall() or []
 
-
     def _sum_debit(self, accounts, date1, date2):
-
-        year=[]
-        res=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
+        account_analytic_obj = self.pool.get('account.analytic.account')
+        year = [int(date1[0:4])-1, int(date1[0:4])]
         ids = map(lambda x: x.id, accounts)
         if not len(ids):
             return 0.0
-        account_analytic_obj = self.pool.get('account.analytic.account')
-        ids2 = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', ids)])
+
+        ids2 = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', ids)])
         self.cr.execute("SELECT sum(amount) as sum \
             FROM account_analytic_line \
             WHERE account_id in ("+ ','.join(map(str, ids2)) + " )  \
@@ -175,20 +150,16 @@
                  and date_part('year',date) in ("+ ','.join(map(str, year)) + " ) \
                  group by date_part('year',date) ",
             (date1[5:10], date2[5:10]))
-        res= self.cr.dictfetchall()
-        return res
+
+        return self.cr.dictfetchall()
 
     def _sum_credit(self, accounts, date1, date2):
-        year=[]
-        year.append(int(date1[0:4])-1)
-        year.append(int(date1[0:4]))
+        account_analytic_obj = self.pool.get('account.analytic.account')
+        year = [int(date1[0:4])-1, int(date1[0:4])]
         ids = map(lambda x: x.id, accounts)
         if not len(ids):
             return 0.0
-        ids = map(lambda x: x.id, accounts)
-        account_analytic_obj = self.pool.get('account.analytic.account')
-        ids2 = account_analytic_obj.search(self.cr, self.uid,
-                [('parent_id', 'child_of', ids)])
+        ids2 = account_analytic_obj.search(self.cr, self.uid, [('parent_id', 'child_of', ids)])
         self.cr.execute("SELECT -sum(amount) as sum \
                 FROM account_analytic_line \
                WHERE account_id in ("+ ','.join(map(str, ids2)) +") \
@@ -196,21 +167,18 @@
                      and date_part('year',date) in ("+ ','.join(map(str, year)) +") \
                      group by date_part('year',date) ",
                 (date1[5:10], date2[5:10]))
-        res= self.cr.dictfetchall()
-        return res
+        return self.cr.dictfetchall()
+
     def _sum_balance(self, accounts, date1, date2):
         debit = self._sum_debit(accounts, date1, date2) or 0.0
         credit = self._sum_credit(accounts, date1, date2) or 0.0
-        res=[]
-        temp=len(debit)
-        for i in range(temp):
-            res.append(debit[i]['sum']-credit[i]['sum'])
-        return res
-
+        result = []
+        for index in range(len(debit)):
+            result.append(debit[index]['sum'] - credit[index]['sum'])
+        return result
 
 report_sxw.report_sxw('report.account.analytic.account.balance.year',
         'account.analytic.account','addons/training_report/report/analytic_balance_year.rml',
         parser=account_analytic_balance_year, header=False)
 
-
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'training_report/report_training_view.xml'
--- training_report/report_training_view.xml	2010-10-05 14:48:03 +0000
+++ training_report/report_training_view.xml	2011-03-17 10:37:29 +0000
@@ -3,14 +3,6 @@
     <data>
         <menuitem id="menu_training_report" name="Reporting" parent="training.training_mi" sequence="100"/>
 
-        <wizard id="training_session_volume_report_wizard"
-            model="training.session"
-            menu="False"
-            name="training.session.volume.report"
-            string="Report Volume"/>
-
-        <menuitem id="training_report_volume_mi" parent="menu_training_report" type="wizard" action="training_session_volume_report_wizard"/>
-
         <record model="ir.ui.view" id="training_report_wizard_form">
             <field name="name">training_report_wizard</field>
             <field name="model">training.report.wizard</field>
@@ -84,5 +76,6 @@
                 </graph>
             </field>
         </record>
+
     </data>
 </openerp>

=== modified file 'training_report/training_report.py'
--- training_report/training_report.py	2011-02-09 15:47:36 +0000
+++ training_report/training_report.py	2011-03-17 10:37:29 +0000
@@ -20,10 +20,9 @@
 #
 ##############################################################################
 
+from osv import osv
+from osv import fields
 import time
-import datetime
-from osv import fields,osv
-import tools
 from tools.sql import drop_view_if_exists
 import xlwt
 import base64
@@ -36,14 +35,14 @@
 from training.training import training_course_kind_compute
 
 # http://code.activestate.com/recipes/476197-first-last-day-of-the-month/#c1
-def get_first_day(dt, d_years=0, d_months=0):
-    # d_years, d_months are "deltas" to apply to dt
-    y, m = dt.year + d_years, dt.month + d_months
-    a, m = divmod(m-1, 12)
-    return date(y+a, m+1, 1)
+def get_first_day(date, date_years=0, date_months=0):
+    # date_years, date_months are "deltas" to apply to date
+    year, month = date.year + date_years, datet.month + date_months
+    avg, month = divmod(month - 1, 12)
+    return date(year + avg, month + 1, 1)
 
-def get_last_day(dt):
-    return get_first_day(dt, 0, 1) + timedelta(-1)
+def get_last_day(date):
+    return get_first_day(date, 0, 1) + timedelta(-1)
 
 
 class subscription_line(osv.osv):
@@ -129,21 +128,11 @@
 class training_report_wizard(osv.osv):
     _name = 'training.report.wizard'
 
-
     _columns = {
         'date_start' : fields.date('Date Start', required=True),
         'date_stop' : fields.date('Date Stop', required=True),
-
-        'state' : fields.selection([('init', 'Init'),
-                                    ('result', 'Result')],
-                                   'State',
-                                   required=True,
-                                   readonly=True),
-
-        'report' : fields.selection([(report_name, report['title']) for report_name, report in REPORTS.iteritems()],
-                                    'Report',
-                                    required=True),
-
+        'state' : fields.selection([('init', 'Init'),('result', 'Result')], 'State', required=True, readonly=True),
+        'report' : fields.selection([(report_name, report['title']) for report_name, report in REPORTS.iteritems()], 'Report', required=True),
         'filename' : fields.char('Filename', size=128, readonly=True),
         'file_data' : fields.binary('File', readonly=True),
     }
@@ -155,11 +144,14 @@
         'state' : lambda *a: 'init',
     }
 
-
     def action_close(self, cr, uid, ids, context=None):
         return {'type' : 'ir.actions.act_window_close'}
 
     def action_generate_report(self, cr, uid, ids, context=None):
+        if not ids:
+            return False
+        if context is None:
+            context = {}
         def execute_query(group_column, column_name):
             cr.execute("""
                 SELECT l.%(gc)s as %(cn)s,
@@ -225,6 +217,7 @@
                             """ % {'gc': group_column, 'cn': column_name}
             , (this.date_start, this.date_stop))
             return cr.fetchall()
+
         def stream_write_row(row_id, values):
             row = stream.row(row_id)
             for idx, value in enumerate(values):
@@ -277,14 +270,14 @@
 
 
         if this.report == 'sale.partner':
-            for x in execute_query_invoice('partner_id', 'partner_id'):
-                row_id = write_to_xls(row_id, x)
+            for temp in execute_query_invoice('partner_id', 'partner_id'):
+                row_id = write_to_xls(row_id, temp)
         elif this.report == 'sale.supplier':
-            for x in execute_query_invoice_supplier('partner_id', 'partner_id'):
-                row_id = write_to_xls(row_id, x)
+            for temp in execute_query_invoice_supplier('partner_id', 'partner_id'):
+                row_id = write_to_xls(row_id, temp)
         elif this.report == 'sale.user':
-            for x in execute_query('create_uid', 'user_id'):
-                row_id = write_to_xls(row_id, x)
+            for temp in execute_query('create_uid', 'user_id'):
+                row_id = write_to_xls(row_id, temp)
         elif this.report == 'sale.offer':
             cr.execute("""
                 SELECT l.offer_id as offer_id,
@@ -303,11 +296,11 @@
               GROUP BY l.offer_id
                        """, (this.date_start, this.date_stop))
 
-            for x in cr.fetchall():
-                row_id = write_to_xls(row_id, x)
+            for temp in cr.fetchall():
+                row_id = write_to_xls(row_id, temp)
         elif this.report == 'sale.product':
-            for x in execute_query('product_id', 'product_id'):
-                row_id = write_to_xls(row_id, x)
+            for temp in execute_query('product_id', 'product_id'):
+                row_id = write_to_xls(row_id, temp)
         elif this.report == 'subscription.offer':
             cr.execute("""
                     SELECT toff.id AS offer_id,
@@ -328,8 +321,8 @@
                   GROUP BY toff.id, toff.kind
                   ORDER BY turnover DESC
                        """, (this.date_start, this.date_stop))
-            for x in cr.fetchall():
-                row_id = write_to_xls(row_id, x)
+            for temp in cr.fetchall():
+                row_id = write_to_xls(row_id, temp)
 
         wb.save(strIO)
 
@@ -383,6 +376,7 @@
         'offer_kind': fields.char('Offer Kind', size=16, readonly=True,),
         'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True,),
     }
+
 training_report_intra_session_seance_view()
 
 class training_report_session_stats_view(osv.osv):
@@ -444,45 +438,47 @@
     }
 
     def init(self, cr):
-        drop_view_if_exists(cr, 'training_report_seance_stats_view', cascade=True)
+        drop_view_if_exists(cr, 'training_report_seance_purchase_stats_view')
+        drop_view_if_exists(cr, 'training_report_seance_stats_view')
         cr.execute("""CREATE OR REPLACE VIEW training_report_seance_stats_view AS (
 
-select
-	tsea.id AS seance_id,
-	tsea.kind,
-        tsea.duration,
-        tsea.course_id,
-	tg.name AS group_name,
-	COALESCE(CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END, 0) AS participant_count,
-	CASE WHEN tsea.kind = 'exam' THEN pp.id ELSE tct.product_id END AS product_id,
-	CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END AS product_price,
-        COALESCE(tsea.duration * (CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END) / (CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END), 0.0) AS one_trainer_cost,
-
-	COALESCE((tsea.duration * (CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END) / (CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END)) * (CASE WHEN tsea.kind = 'exam' AND tsea.course_id IS NULL THEN 2.0 ELSE 1.0 END), 0.0) AS trainer_cost
-
-
-FROM
-	training_seance tsea
-LEFT JOIN
-	training_participation tp ON (tp.group_id = tsea.group_id AND tp.seance_id = tsea.id)
-INNER JOIN
-	product_product pp ON (pp.default_code = 'R50H')
-LEFT JOIN
-	training_course tc ON (tsea.kind != 'exam' AND tsea.course_id = tc.id)
-LEFT JOIN
-	training_course_type tct ON (tc.course_type_id = tct.id)
-LEFT JOIN
-	training_group tg ON (tsea.group_id = tg.id)
-LEFT JOIN
-        product_product pp2 ON (tct.product_id = pp2.id)
-LEFT JOIN
-        product_template pt ON (pp.product_tmpl_id = pt.id)
-LEFT JOIN
-        product_template pt2 ON (pp2.product_tmpl_id = pt2.id)
-GROUP BY
-	tsea.id, tsea.kind, tsea.duration, tsea.course_id, tg.name, tsea.manual, tsea.participant_count_manual, pp.id, tct.product_id, pt.standard_price, pt2.standard_price
-
-        )""")
+                    select
+                    	tsea.id AS seance_id,
+                    	tsea.kind,
+                            tsea.duration,
+                            tsea.course_id,
+                    	tg.name AS group_name,
+                    	COALESCE(CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END, 0) AS participant_count,
+                    	CASE WHEN tsea.kind = 'exam' THEN pp.id ELSE tct.product_id END AS product_id,
+                    	CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END AS product_price,
+                            COALESCE(tsea.duration * (CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END) / (CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END), 0.0) AS one_trainer_cost,
+
+                    	COALESCE((tsea.duration * (CASE WHEN tsea.kind = 'exam' THEN pt.standard_price ELSE pt2.standard_price END) / (CASE WHEN (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END ) <= 0 THEN 1 ELSE (CASE WHEN tsea.manual THEN tsea.participant_count_manual ELSE count(tp.id) END) END)) * (CASE WHEN tsea.kind = 'exam' AND tsea.course_id IS NULL THEN 2.0 ELSE 1.0 END), 0.0) AS trainer_cost
+
+
+                    FROM
+                    	training_seance tsea
+                    LEFT JOIN
+                    	training_participation tp ON (tp.group_id = tsea.group_id AND tp.seance_id = tsea.id)
+                    INNER JOIN
+                    	product_product pp ON (pp.default_code = 'R50H')
+                    LEFT JOIN
+                    	training_course tc ON (tsea.kind != 'exam' AND tsea.course_id = tc.id)
+                    LEFT JOIN
+                    	training_course_type tct ON (tc.course_type_id = tct.id)
+                    LEFT JOIN
+                    	training_group tg ON (tsea.group_id = tg.id)
+                    LEFT JOIN
+                            product_product pp2 ON (tct.product_id = pp2.id)
+                    LEFT JOIN
+                            product_template pt ON (pp.product_tmpl_id = pt.id)
+                    LEFT JOIN
+                            product_template pt2 ON (pp2.product_tmpl_id = pt2.id)
+                    GROUP BY
+                    	tsea.id, tsea.kind, tsea.duration, tsea.course_id, tg.name, tsea.manual, tsea.participant_count_manual, pp.id, tct.product_id, pt.standard_price, pt2.standard_price
+
+                            )""")
+
 training_report_seance_stats_view()
 
 class training_report_seance_purchase_stats_view(osv.osv):
@@ -507,16 +503,17 @@
         )""")
 
     _columns = {
-        'seance_id': fields.many2one('training.seance', 'Seance', readonly=True,),
-        'product_id': fields.many2one('product.product', 'Product', readonly=True,),
-        'total_qty': fields.integer('Total Product Quantity', readonly=True,),
-        'attachment_id': fields.many2one('ir.attachment', 'Attachment', readonly=True,),
-        'standard_price': fields.float('Product Standard Price', readonly=True,),
+        'seance_id': fields.many2one('training.seance', 'Seance', readonly=True),
+        'product_id': fields.many2one('product.product', 'Product', readonly=True),
+        'total_qty': fields.integer('Total Product Quantity', readonly=True),
+        'attachment_id': fields.many2one('ir.attachment', 'Attachment', readonly=True),
+        'standard_price': fields.float('Product Standard Price', readonly=True),
         'attachment_price': fields.float('Attachment Price', readonly=True),
         'price': fields.float('Purchase Line Price', readonly=True),
         'procurement_method': fields.char('Procurement Method', size=16, readonly=True),
         'procurement_price': fields.char('Procurement Price', size=16, readonly=True),
     }
+
 training_report_seance_purchase_stats_view()
 
 class training_report_costs_view(osv.osv):
@@ -525,16 +522,16 @@
     _auto = False
 
     _columns = {
-        'session_id': fields.many2one('training.session', 'Session', ),
-        'session_date': fields.datetime('Session Date'),
-        'seance_id': fields.many2one('training.seance', 'Seance', ),
-        'seance_kind': fields.selection(training_course_kind_compute, 'Seance Kind', ),
-        'seance_date': fields.datetime('Seance Date'),
-        'offer_kind': fields.selection(training_offer_kind_compute, 'Offer Kind', ),
-        'offer_id': fields.many2one('training.offer', 'Offer'),
-        'computed_course_id': fields.many2one('training.course', 'Course', ),
-        'computed_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account', ),
-        'product_line_id': fields.many2one('training.course_category', 'Product Line', ),
+        'session_id': fields.many2one('training.session', 'Session', readonly=True),
+        'session_date': fields.datetime('Session Date', readonly=True),
+        'seance_id': fields.many2one('training.seance', 'Seance', readonly=True),
+        'seance_kind': fields.selection(training_course_kind_compute, 'Seance Kind', readonly=True),
+        'seance_date': fields.datetime('Seance Date', readonly=True),
+        'offer_kind': fields.selection(training_offer_kind_compute, 'Offer Kind', readonly=True),
+        'offer_id': fields.many2one('training.offer', 'Offer', readonly=True),
+        'computed_course_id': fields.many2one('training.course', 'Course', readonly=True),
+        'computed_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
+        'product_line_id': fields.many2one('training.course_category', 'Product Line', readonly=True),
     }
 
     def init(self, cr):
@@ -577,20 +574,19 @@
         for sess_stats in cr.dictfetchall():
             sess_stats['duration'] = sess_stats['seances_duration']
             cache_session[sess_stats['session_id']] = sess_stats
+        return True
 
     def docache_seance_populate(self, cr, uid, cache_seance, seance_ids):
         if not seance_ids:
             return
-
         query_seance_ids = ','.join(map(str, seance_ids))
-
         # pre-compute procurement price
         seance_procs_cache = {}
         for seance_id in seance_ids:
             seance_procs_cache[seance_id] = {
-                'proc_fix': 0.0,
-                'proc_sub': 0.0,
-            }
+                            'proc_fix': 0.0,
+                            'proc_sub': 0.0,
+                        }
         cr.execute("SELECT * FROM training_report_seance_purchase_stats_view trspsv WHERE seance_id IN (%s)" % (query_seance_ids))
         for purch_stat in cr.dictfetchall():
             price = purch_stat['price']
@@ -610,6 +606,7 @@
             seance_stats['sessions_ratio'] = {}
 
             cache_seance[seance_stats['seance_id']] = seance_stats
+        return True
 
     def docache_session(self, cache_session, session):
         if session.id not in cache_session:
@@ -618,6 +615,7 @@
                 'subscription_count': session.confirmed_subscriptions,
                 'duration': (sum([ seance.duration for seance in session.seance_ids]) or 1.0) / (float(len(session.group_ids)) or 1.0)
             }
+        return True
 
     def docache_seance(self, cr, uid, cache_seance, seance, context=None):
         if seance.id not in cache_seance:
@@ -662,6 +660,7 @@
                 'group': seance.group_id.name,
                 'sessions_ratio': {},
             }
+        return True
 
 #        print("          group class      : %s" % (cache_seance[seance.id]['group']))
 #        print("          trainer cost     : %s" % (cache_seance[seance.id]['trainer_cost']))
@@ -669,16 +668,18 @@
 #        print("          participant cnt  : %s" % (cache_seance[seance.id]['participants']))
 
     def get_sale_price(self, cr, uid, theor_cost, context=None):
+        if context is None:
+            context = {}
         offer_pool = self.pool.get('training.offer')
         subl_pool = self.pool.get('training.subscription.line')
         price = 0.0
-        if theor_cost['offer_kind'] == 'intra':
-            o = offer_pool.browse(cr, uid, theor_cost['offer_id'])
-            pcount = o.number_of_participants or 12
-            price = (o.sale_order_id and o.sale_order_id.amount_untaxed or 0.0) / pcount
+        if theor_cost.get('offer_kind',False) == 'intra':
+            offer_data = offer_pool.browse(cr, uid, theor_cost['offer_id'])
+            participant_count = offer_data.number_of_participants or 12
+            price = (offer_data.sale_order_id and offer_data.sale_order_id.amount_untaxed or 0.0) / participant_count
         else:
             #price = subl_pool.read(cr, uid, theor_cost['id'], ['price'])['price']
-            price = theor_cost['subl_price']
+            price = theor_cost.get('subl_price')
         return price
 
 training_report_costs_view()
@@ -716,7 +717,7 @@
     }
 
     def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
-        if not context:
+        if context is None:
             context = {}
         if context.get('date_filter', '') == 'current_year':
             args.extend([('date','>=',time.strftime('%Y-01-01')),('date','<=',time.strftime('%Y-12-31'))])
@@ -725,10 +726,8 @@
 #            month_start_dt = datetime.datetime(map(int, month_start.split('-')))
 #            month_end = get_last_day(month_start_dt, d_month=1).strftime('%Y-%m-%d')
 #            args.extend
-        r = super(training_report_confirmed_subscription_count, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
-        return r
+        return super(training_report_confirmed_subscription_count, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
 
 training_report_confirmed_subscription_count()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-

=== modified file 'training_report/training_report.xml'
--- training_report/training_report.xml	2009-11-25 16:36:08 +0000
+++ training_report/training_report.xml	2011-03-17 10:37:29 +0000
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <openerp>
     <data>
+
         <report auto="False"
             id="account_analytic_account_balance"
             menu="False"
@@ -9,12 +10,6 @@
             rml="/training_report/report/analytic_balance_year.rml"
             string="Analytic Balance Year"/>
 
-        <wizard id="account_analytic_account_balance_report_year"
-            keyword="client_print_multi"
-            model="account.analytic.account"
-            name="account.analytic.account.balance.year.report"
-            string="Analytic Balance Year"/>
-
         <report auto="False"
             id="course_profitability"
             menu="False"
@@ -24,13 +19,5 @@
             rml="training_report/report/course_profitability.rml"
             />
 
-        <wizard id="course_profitability_report"
-            keyword="client_print_multi"
-            model="training.course"
-            name="training.course.profitability.report"
-            string="Course Profitablility"/>
-
-
-
     </data>
 </openerp>

=== modified file 'training_report/wizard/__init__.py'
--- training_report/wizard/__init__.py	2010-03-10 20:55:08 +0000
+++ training_report/wizard/__init__.py	2011-03-17 10:37:29 +0000
@@ -21,9 +21,9 @@
 ##############################################################################
 
 
-import wizard_account_analytic_balance_report_year_to_date
-import wizard_course_profitability
-import wizard_session_volume
+import training_report_account_analytic_balance_year
+import training_report_course_profitability
+import training_report_session_volume
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 

=== renamed file 'training_report/wizard/wizard_account_analytic_balance_report_year_to_date.py' => 'training_report/wizard/training_report_account_analytic_balance_year.py'
--- training_report/wizard/wizard_account_analytic_balance_report_year_to_date.py	2009-11-25 16:36:08 +0000
+++ training_report/wizard/training_report_account_analytic_balance_year.py	2011-03-17 10:37:29 +0000
@@ -20,38 +20,36 @@
 #
 ##############################################################################
 
+
+from osv import osv
+from osv import fields
 import time
-import wizard
-import datetime
-
-dates_form = '''<?xml version="1.0"?>
-<form string="Select period">
-    <field name="date1"/>
-    <field name="date2"/>
-</form>'''
-
-dates_fields = {
-    'date1': {'string':'Start of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-01-01')},
-    'date2': {'string':'End of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
-}
-
-
-class wizard_report(wizard.interface):
-
-
-    states = {
-        'init': {
-            'actions': [],
-            'result': {'type':'form', 'arch':dates_form, 'fields':dates_fields, 'state':[('end','Cancel'), ('report','Print')]}
-        },
-        'report': {
-            'actions': [],
-            'result': {'type':'print', 'report':'account.analytic.account.balance.year', 'state':'end'}
+
+class training_report_account_analytic_balance_year(osv.osv_memory):
+    _name = 'training.report.account.analytic.balance.year'
+    _columns = {
+    'date1' : fields.date('Start of period', required=True),
+    'date2' : fields.date('End of period', required=True),
+    }
+
+    _defaults = {
+        'date1': lambda *a: time.strftime('%Y-01-01'),
+        'date2': lambda *a: time.strftime('%Y-%m-%d'),
+    }
+
+    def action_report(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        datas = {'form':{}, 'ids': context.get('active_ids', [])}
+        res = self.read(cr, uid, ids, ['date1', 'date2'], context)
+        res = res and res[0] or {}
+        datas['form'].update(res)
+        return {
+            'type': 'ir.actions.report.xml',
+            'report_name': 'account.analytic.account.balance.year',
+            'datas': datas,
         }
-    }
-wizard_report('account.analytic.account.balance.year.report')
-
-
+
+training_report_account_analytic_balance_year()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-

=== added file 'training_report/wizard/training_report_account_analytic_balance_year_view.xml'
--- training_report/wizard/training_report_account_analytic_balance_year_view.xml	1970-01-01 00:00:00 +0000
+++ training_report/wizard/training_report_account_analytic_balance_year_view.xml	2011-03-17 10:37:29 +0000
@@ -0,0 +1,35 @@
+<openerp>
+    <data>
+
+        <record model="ir.ui.view" id="training_report_account_analytic_balance_year_form">
+            <field name="name">training.report.account.analytic.balance.year.form</field>
+            <field name="model">training.report.account.analytic.balance.year</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Analytic Balance Year">
+                    <field name="date1"/>
+                    <field name="date2"/>
+                    <separator colspan="4" />
+                    <group colspan="4" col="2">
+                        <button string="Cancel" special="cancel" type="object" icon="gtk-cancel"/>
+                        <button name="action_report" string="Print" type="object" icon="gtk-print"/>
+                    </group>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="training_report_account_analytic_balance_year_form_act">
+            <field name="name">Analytic Balance Year</field>
+            <field name="res_model">training.report.account.analytic.balance.year</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <act_window id="action_act_training_report_account_analytic_balance_year"
+            key2="client_action_multi" name="Analytic Balance Year"
+            res_model="training.report.account.analytic.balance.year" src_model="account.analytic.account"
+            view_mode="form" target="new" view_type="form"/>
+
+    </data>
+</openerp>

=== renamed file 'training_report/wizard/wizard_course_profitability.py' => 'training_report/wizard/training_report_course_profitability.py'
--- training_report/wizard/wizard_course_profitability.py	2009-11-25 16:36:08 +0000
+++ training_report/wizard/training_report_course_profitability.py	2011-03-17 10:37:29 +0000
@@ -20,42 +20,39 @@
 #
 ##############################################################################
 
+
+from osv import osv
+from osv import fields
 import time
-import wizard
-import datetime
-
-dates_form = '''<?xml version="1.0"?>
-<form string="Select period">
-    <field name="date1"/>
-    <field name="date2"/>
-    <field name="analytic_account"/>
-    <field name="analytic_fix_cost"/>
-</form>'''
-
-dates_fields = {
-    'date1': {'string':'Start of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-01-01')},
-    'date2': {'string':'End of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
-    'analytic_account':{'string':'Analytic Account', 'type':'many2one','relation': 'account.analytic.account', 'required':True},
-    'analytic_fix_cost':{'string':'Analytic Fix Cost', 'type':'float'},
-}
-
-
-class wizard_report(wizard.interface):
-
-
-    states = {
-        'init': {
-            'actions': [],
-            'result': {'type':'form', 'arch':dates_form, 'fields':dates_fields, 'state':[('end','Cancel'), ('report','Print')]}
-        },
-        'report': {
-            'actions': [],
-            'result': {'type':'print', 'report':'training.course.profitability', 'state':'end'}
+
+class training_report_course_profitability(osv.osv_memory):
+    _name = 'training.report.course.profitability'
+    _columns = {
+    'date1' : fields.date('Start of period', required=True),
+    'date2' : fields.date('End of period', required=True),
+    'analytic_account' : fields.many2one('account.analytic.account', 'Analytic Account', required=True),
+    'analytic_fix_cost' : fields.float('Analytic Fix Cost'),
+    }
+
+
+    _defaults = {
+        'date1': lambda *a: time.strftime('%Y-01-01'),
+        'date2': lambda *a: time.strftime('%Y-%m-%d'),
+    }
+
+    def action_report(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        datas = {'form':{}, 'ids': context.get('active_ids', [])}
+        res = self.read(cr, uid, ids, ['date1', 'date2', 'analytic_account', 'analytic_fix_cost'], context)
+        res = res and res[0] or {}
+        datas['form'].update(res)
+        return {
+            'type': 'ir.actions.report.xml',
+            'report_name': 'training.course.profitability',
+            'datas': datas,
         }
-    }
-wizard_report('training.course.profitability.report')
-
-
+
+training_report_course_profitability()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-

=== added file 'training_report/wizard/training_report_course_profitability_view.xml'
--- training_report/wizard/training_report_course_profitability_view.xml	1970-01-01 00:00:00 +0000
+++ training_report/wizard/training_report_course_profitability_view.xml	2011-03-17 10:37:29 +0000
@@ -0,0 +1,37 @@
+<openerp>
+    <data>
+
+        <record model="ir.ui.view" id="view_training_report_course_profitability_form">
+            <field name="name">training.report.course.profitability.form</field>
+            <field name="model">training.report.course.profitability</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+				<form string="Course Profitablility">
+				    <field name="date1"/>
+				    <field name="date2"/>
+				    <field name="analytic_account"/>
+				    <field name="analytic_fix_cost"/>
+				    <separator colspan="4" />
+                    <group colspan="4" col="2">
+                        <button string="Cancel" special="cancel" type="object" icon="gtk-cancel"/>
+                        <button name="action_report" string="Print" type="object" icon="gtk-print"/>
+                    </group>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="training_report_course_profitability_form_act">
+            <field name="name">Course Profitablility</field>
+            <field name="res_model">training.report.course.profitability</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <act_window id="action_act_training_report_course_profitability"
+            key2="client_action_multi" name="Course Profitablility"
+            res_model="training.report.course.profitability" src_model="training.course"
+            view_mode="form" target="new" view_type="form"/>
+
+    </data>
+</openerp>

=== renamed file 'training_report/wizard/wizard_session_volume.py' => 'training_report/wizard/training_report_session_volume.py'
--- training_report/wizard/wizard_session_volume.py	2010-09-22 10:00:18 +0000
+++ training_report/wizard/training_report_session_volume.py	2011-03-17 10:37:29 +0000
@@ -20,433 +20,383 @@
 #
 ##############################################################################
 
-import wizard
+from osv import osv
+from osv import fields
 import time
-import datetime
-import pooler
 import tools
 
 from tools.translate import _
 import mx.DateTime as dt
 
-_aged_trial_form = """<?xml version="1.0"?>
-<form string="Session Volume Report">
-    <separator string="Period" colspan="4" />
-    <field name="date_start"/>
-    <field name="date_stop"/>
-    <separator string="Year" colspan="4" />
-    <field name="year" />
-    <separator string="Report" colspan="4" />
-    <field name="kind" />
-</form>"""
-
-def first_day_of_previous_month():
-    return dt.strptime((dt.today() - dt.RelativeDate(months=1)).strftime('%Y-%m-01'), '%Y-%m-%d')
-
-def last_day_of_previous_month():
-    return first_day_of_previous_month() + dt.RelativeDate(months=1, seconds=-1)
-
-_aged_trial_fields = {
-    'date_start': {'string':'Start of period', 'type':'date', 'required':True, 'default': lambda *a: first_day_of_previous_month().strftime('%Y-%m-%d')},
-    'date_stop': {'string':'Stop of period', 'type':'date', 'required':True, 'default': lambda *a: last_day_of_previous_month().strftime('%Y-%m-%d')},
-    'year': {'string':'Year', 'type':'integer', 'required':True, 'default': lambda *a: -1},
-    'kind' : {'string' : 'Kind',
-              'type' : 'selection',
-              'selection' : [
+class training_report_session_volume(osv.osv_memory):
+    _name = 'training.report.session.volume'
+    _columns = {
+    'date_start' : fields.date('Start of period', required=True),
+    'date_stop' : fields.date('End of period', required=True),
+    'year' : fields.integer('Year', required=True),
+    'kind' : fields.selection([
                   ('product_lines', 'Statistics by Product Lines'),
                   ('theoretical_product_lines', 'Theoretical Statistics by Product Lines'),
                   ('sessions', 'Sessions volume by State'),
                   ('count_subscriptions_offer', 'Subscription Volume by State'),
                   #('subscriptions_partner', 'Partner Amount of Subscriptions'),
-              ],
-              'default' : lambda *a: 'product_lines'}
-}
-
-def previous_date(date, year):
-    return dt.strptime(date, '%Y-%m-%d') + dt.RelativeDate(years=year)
-
-def previous_period(date_start, date_stop, year):
-    return (previous_date(date_start, year), previous_date(date_stop, year))
-
-def compute_theoretical_product_lines(cr, uid, ids, context, date_start, date_stop, kind):
-#    print(">>> --== Compute Theoretical Product Lines ==--")
-    pool = pooler.get_pool(cr.dbname)
-    session_pool = pool.get('training.session')
-    subl_pool = pool.get('training.subscription.line')
-    prodline_pool = pool.get('training.course_category')
-    offer_pool = pool.get('training.offer')
-    trcv_pool = pool.get('training.report.costs.view')
-
-    cache_seance = {}
-    cache_session = {}
-    product_line = {} # dict containing cost + revenue per product lines
-
-    query_base = "SELECT * FROM training_report_costs_view "
-    query = "WHERE seance_date BETWEEN %s AND %s AND offer_kind = %s"
-    query_args = (date_start, date_stop, kind)
-
-    if kind == 'intra':
-        cr.execute("SELECT DISTINCT(session_id) FROM training_report_intra_session_seance_view " + query, query_args)
-    else:
-        cr.execute("SELECT DISTINCT(session_id) FROM training_report_costs_view " + query, query_args)
-    session_ids = [ x[0] for x in cr.fetchall() ]
-    trcv_pool.docache_session_populate(cr, uid, cache_session, session_ids)
-
-    if kind == 'intra':
-        cr.execute("SELECT DISTINCT(seance_id) FROM training_report_intra_session_seance_view " + query, query_args)
-    else:
-        cr.execute("SELECT DISTINCT(seance_id) FROM training_report_costs_view " + query, query_args)
-    seance_ids = [ x[0] for x in cr.fetchall() ]
-    trcv_pool.docache_seance_populate(cr, uid, cache_seance, seance_ids)
-
-    if kind != 'intra':
-        cr.execute(query_base + query, query_args)
-        for theor_cost in cr.dictfetchall():
-            c_session_id = theor_cost['session_id']
-            c_seance_id = theor_cost['seance_id']
-
-            if c_session_id not in cache_seance[c_seance_id]['sessions_ratio']:
-                # seance already cached, but we still need to update the session ratio
-                session_total_duration = cache_session[theor_cost['session_id']]['duration']
-                cache_seance[c_seance_id]['sessions_ratio'][c_session_id] = cache_seance[c_seance_id]['duration'] / session_total_duration
-
-            # all things are cached now
-            c_seance = cache_seance[theor_cost['seance_id']]
-            c_prodline_id = theor_cost['product_line_id']
-            if c_prodline_id not in product_line:
-                plo = prodline_pool.browse(cr, uid, c_prodline_id)
-                product_line[c_prodline_id] = {
-                    'id': c_prodline_id,
-                    'name': plo.name,
-                    'costs': 0.0,
-                    'revenues': 0.0,
-                    'subscriptions': set(),
-                }
-            pl = product_line[c_prodline_id]
-            pl['costs'] += c_seance['trainer_cost'] + c_seance['proc_cost']
-            pl['revenues'] += c_seance['sessions_ratio'][theor_cost['session_id']] * trcv_pool.get_sale_price(cr, uid, theor_cost, context=context)
-            pl['subscriptions'].add(theor_cost['id'])
-    else: # kind == 'intra'
-        cr.execute("SELECT * FROM training_report_intra_session_seance_view " + query, query_args)
-        for theor_intra in cr.dictfetchall():
-            c_session_id = theor_intra['session_id']
-            c_seance_id = theor_intra['seance_id']
-
-            if c_session_id not in cache_seance[c_seance_id]['sessions_ratio']:
-                # seance already cached, but we still need to update the session ratio
-                session_total_duration = cache_session[theor_intra['session_id']]['duration']
-                cache_seance[c_seance_id]['sessions_ratio'][c_session_id] = cache_seance[c_seance_id]['duration'] / session_total_duration
-
-            c_seance = cache_seance[theor_intra['seance_id']]
-            c_session = cache_session[theor_intra['session_id']]
-
-            c_session_ratio = cache_seance[c_seance_id]['sessions_ratio'][c_session_id]
-
-            c_prodline_id = theor_intra['product_line_id']
-            if c_prodline_id not in product_line:
-                plo = prodline_pool.browse(cr, uid, c_prodline_id)
-                product_line[c_prodline_id] = {
-                    'id': c_prodline_id,
-                    'name': plo.name,
-                    'costs': 0.0,
-                    'revenues': 0.0,
-                    'subscriptions': set(),
-                }
-            pl = product_line[c_prodline_id]
-            pl['costs'] += c_session_ratio * theor_intra['session_cost']
-            pl['revenues'] += c_session_ratio * theor_intra['session_revenue']
-            for x in xrange(1, theor_intra['number_of_participants'] + 1):
-                pl['subscriptions'].add(x)
-
-    res = []
-    total = { 'revenues': 0.0, 'costs': 0.0 }
-    for p, v in product_line.iteritems():
-        res.append(v)
-        v['subscriptions'] = len(v['subscriptions'])
-        v['margin'] = (v['revenues'] / (v['costs'] or 1.0)) * 100
-        v['balance'] = (v['revenues'] - v['costs'])
-        total['revenues'] += v['revenues']
-        total['costs'] += v['costs']
-
-    total['balance'] = total['revenues'] - total['costs']
-    total['margin'] = (total['revenues'] / (total['costs'] or 1.0)) * 100
-
-    return {
-        'product_lines': res,
-        'total': total,
-        'date_start': date_start,
-        'date_stop': date_stop,
-        'kind': kind,
-    }
-
-def compute_product_lines_exam(cr, uid, ids, context, date_start, date_stop):
-    res = []
-
-
-    pool = pooler.get_pool(cr.dbname)
-
-    tsl_proxy = pool.get('training.subscription.line')
-
-    tsl_ids = tsl_proxy.search(cr, uid,
-                               [
-                                   ('state', 'not in', ('draft', 'cancelled')),
-                                   ('date', '>=', "%s 00:00:00" % (date_start)),
-                                   ('date', '<=', "%s 23:59:59" % (date_stop)),
-                                   ('kind', '=', 'exam'),
-                               ],
-                               context=context)
-
-    product_lines = {}
-
-    for sl in tsl_proxy.browse(cr, uid, tsl_ids, context=context):
-
-        if not (sl.course_id and sl.course_id.category_id):
-            continue
-
-        product_line_id = sl.course_id.category_id
-
-        product_lines.setdefaults(product_line_id, [])
-
-        if sl.invoice_line_id and sl.invoice_id:
-            product_lines[product_line_id].append(sl)
-
-
-def compute_product_lines(cr, uid, ids, context, date_start, date_stop, kind):
-    res = []
-
-    pool = pooler.get_pool(cr.dbname)
-    tsl_proxy = pool.get('training.subscription.line')
-
-    tsl_ids = tsl_proxy.search(cr, uid,
-                               [
-                                   ('state', 'not in', ('draft', 'cancelled')),
-                                   ('date', '>=', "%s 00:00:00" % (date_start)),
-                                   ('date', '<=', "%s 23:59:59" % (date_stop)),
-                                   ('kind', '=', kind),
-                               ],
-                               context=context)
-
-    product_lines = {}
-
-    for sl in tsl_proxy.browse(cr, uid, tsl_ids, context=context):
-
-        session_id = sl.session_id
-        invoice_id = sl.invoice_id
-
-        product_line_id = sl.session_id.offer_id.product_line_id
-
-        product_lines.setdefault(product_line_id,
-                                 {
-                                     'invoices' : set(),
-                                     'sessions' : {},
-                                     'subscription_count' : 0,
-                                     'exams' : {},
-                                 }
-                                )
-
-        product_lines[product_line_id]['subscription_count'] += 1
-
-        if invoice_id and sl.invoice_line_id:
-            product_lines[product_line_id]['invoices'].add(invoice_id)
-
-        if sl.session_id not in product_lines[product_line_id]['sessions']:
-
-            po_pool = pool.get('purchase.order')
-            sl_sess_seance_ids = [ seance.id for seance in session_id.seance_ids ]
-            sl_sess_po = po_pool.search(cr, uid, [('seance_id','in',sl_sess_seance_ids)], context=context)
-            value = sum(po.invoice_id and po.invoice_id.amount_untaxed or po.amount_untaxed
-                        for po in po_pool.browse(cr, uid, sl_sess_po, context=context))
-            #value = sum(po.procurement_id.purchase_id.amount_total
-            #            for seance in session_id.seance_ids
-            #            for po in seance.purchase_line_ids
-            #            if po.procurement_id and po.procurement_id.purchase_id)
-
-            value += sum(request.purchase_order_id.amount_untaxed
-                         for request in session_id.request_ids
-                         if request.purchase_order_id and request.state in ('accepted', 'done'))
-
-            product_lines[product_line_id]['sessions'][sl.session_id] = value
-
-        if sl.kind == 'exam' and sl.course_id and sl.course_id.category_id:
-            product_lines[product_line_id]['exams'].setdefault(sl.course_id.category_id, {'subscription_count' : 0,
-                                                                                          'price' : 0.0,
-                                                                                         }
-                                                              )
-            product_line = product_lines[product_line_id]['exams'][sl.course_id.category_id]
-            product_line['subscription_count'] += 1
-            product_line['price'] += sl.price
-
-    for pl, data in product_lines.iteritems():
-        subscription_count = data['subscription_count']
-
-        pl_input = sum(invoice_id.amount_untaxed for invoice_id in data['invoices'])
-        pl_output = sum( data['sessions'].values() or [0.0])
-
-        pl_balance = pl_input - pl_output
-
-        pl_margin = (pl_input / (pl_output or 1.0)) * 100
-
-        pl_average_price = subscription_count > 0 and (pl_input / subscription_count) or 0
-        pl_yield = subscription_count > 0 and (pl_balance / subscription_count) or 0
-
-        if ((-0.00001 < pl_input < 0.00001) or (-0.00001 < pl_output < 0.00001)):
-            pl_margin = _('N/A')
+              ], 'Kind', required=True)
+    }
+
+    _defaults = {
+        'date_start': lambda self, cr, uid, context: self.first_day_of_previous_month(cr, uid, context).strftime('%Y-%m-%d'),
+        'date_stop': lambda self, cr, uid, context: self.last_day_of_previous_month(cr, uid, context).strftime('%Y-%m-%d'),
+        'year': lambda *a: -1,
+        'kind': lambda *a: 'product_lines',
+    }
+
+
+    def first_day_of_previous_month(self, cr, uid, context=None):
+        return dt.strptime((dt.today() - dt.RelativeDate(months=1)).strftime('%Y-%m-01'), '%Y-%m-%d')
+
+    def last_day_of_previous_month(self, cr, uid, context=None):
+        return self.first_day_of_previous_month(cr, uid, context) + dt.RelativeDate(months=1, seconds=-1)
+
+    def previous_date(self, cr, uid, date, year, context=None):
+        return dt.strptime(date, '%Y-%m-%d') + dt.RelativeDate(years=year)
+
+    def previous_period(self, cr, uid, date_start, date_stop, year, context=None):
+        return (self.previous_date(cr, uid, date_start, year,context), self.previous_date(cr, uid, date_stop, year, context))
+
+    def compute_theoretical_product_lines(self, cr, uid, ids, date_start, date_stop, kind, context=None):
+        if context is None:
+            context = {}
+        session_pool = self.pool.get('training.session')
+        subl_pool = self.pool.get('training.subscription.line')
+        prodline_pool = self.pool.get('training.course_category')
+        offer_pool = self.pool.get('training.offer')
+        trcv_pool = self.pool.get('training.report.costs.view')
+
+        cache_seance = {}
+        cache_session = {}
+        product_line = {} # dict containing cost + revenue per product lines
+
+        query_base = "SELECT * FROM training_report_costs_view "
+        query = "WHERE seance_date BETWEEN %s AND %s AND offer_kind = %s"
+        query_args = (date_start, date_stop, kind)
+
+        if kind == 'intra':
+            cr.execute("SELECT DISTINCT(session_id) FROM training_report_intra_session_seance_view " + query, query_args)
+        else:
+            cr.execute("SELECT DISTINCT(session_id) FROM training_report_costs_view " + query, query_args)
+        session_ids = [ x[0] for x in cr.fetchall() ]
+        trcv_pool.docache_session_populate(cr, uid, cache_session, session_ids)
+
+        if kind == 'intra':
+            cr.execute("SELECT DISTINCT(seance_id) FROM training_report_intra_session_seance_view " + query, query_args)
+        else:
+            cr.execute("SELECT DISTINCT(seance_id) FROM training_report_costs_view " + query, query_args)
+        seance_ids = [ x[0] for x in cr.fetchall() ]
+        trcv_pool.docache_seance_populate(cr, uid, cache_seance, seance_ids)
+
+        if kind != 'intra':
+            cr.execute(query_base + query, query_args)
+            for theor_cost in cr.dictfetchall():
+                c_session_id = theor_cost['session_id']
+                c_seance_id = theor_cost['seance_id']
+
+                if c_session_id not in cache_seance[c_seance_id]['sessions_ratio']:
+                    # seance already cached, but we still need to update the session ratio
+                    session_total_duration = cache_session[theor_cost['session_id']]['duration']
+                    cache_seance[c_seance_id]['sessions_ratio'][c_session_id] = cache_seance[c_seance_id]['duration'] / session_total_duration
+
+                # all things are cached now
+                c_seance = cache_seance[theor_cost['seance_id']]
+                c_prodline_id = theor_cost['product_line_id']
+                if c_prodline_id not in product_line:
+                    plo = prodline_pool.browse(cr, uid, c_prodline_id)
+                    product_line[c_prodline_id] = {
+                        'id': c_prodline_id,
+                        'name': plo.name,
+                        'costs': 0.0,
+                        'revenues': 0.0,
+                        'subscriptions': set(),
+                    }
+                pl = product_line[c_prodline_id]
+                pl['costs'] += c_seance['trainer_cost'] + c_seance['proc_cost']
+                pl['revenues'] += c_seance['sessions_ratio'][theor_cost['session_id']] * trcv_pool.get_sale_price(cr, uid, theor_cost, context=context)
+                pl['subscriptions'].add(theor_cost['id'])
+        else: # kind == 'intra'
+            cr.execute("SELECT * FROM training_report_intra_session_seance_view " + query, query_args)
+            for theor_intra in cr.dictfetchall():
+                c_session_id = theor_intra['session_id']
+                c_seance_id = theor_intra['seance_id']
+
+                if c_session_id not in cache_seance[c_seance_id]['sessions_ratio']:
+                    # seance already cached, but we still need to update the session ratio
+                    session_total_duration = cache_session[theor_intra['session_id']]['duration']
+                    cache_seance[c_seance_id]['sessions_ratio'][c_session_id] = cache_seance[c_seance_id]['duration'] / session_total_duration
+
+                c_seance = cache_seance[theor_intra['seance_id']]
+                c_session = cache_session[theor_intra['session_id']]
+
+                c_session_ratio = cache_seance[c_seance_id]['sessions_ratio'][c_session_id]
+
+                c_prodline_id = theor_intra['product_line_id']
+                if c_prodline_id not in product_line:
+                    plo = prodline_pool.browse(cr, uid, c_prodline_id)
+                    product_line[c_prodline_id] = {
+                        'id': c_prodline_id,
+                        'name': plo.name,
+                        'costs': 0.0,
+                        'revenues': 0.0,
+                        'subscriptions': set(),
+                    }
+                pl = product_line[c_prodline_id]
+                pl['costs'] += c_session_ratio * theor_intra['session_cost']
+                pl['revenues'] += c_session_ratio * theor_intra['session_revenue']
+                for x in xrange(1, theor_intra['number_of_participants'] + 1):
+                    pl['subscriptions'].add(x)
+
+        res = []
+        total = { 'revenues': 0.0, 'costs': 0.0 }
+        for p, v in product_line.iteritems():
+            res.append(v)
+            v['subscriptions'] = len(v['subscriptions'])
+            v['margin'] = (v['revenues'] / (v['costs'] or 1.0)) * 100
+            v['balance'] = (v['revenues'] - v['costs'])
+            total['revenues'] += v['revenues']
+            total['costs'] += v['costs']
+
+        total['balance'] = total['revenues'] - total['costs']
+        total['margin'] = (total['revenues'] / (total['costs'] or 1.0)) * 100
+
+        return {
+            'product_lines': res,
+            'total': total,
+            'date_start': date_start,
+            'date_stop': date_stop,
+            'kind': kind,
+        }
+
+#    def compute_product_lines_exam(self, cr, uid, ids, date_start, date_stop, context=None):
+#        if context is None:
+#            context = {}
+#        tsl_proxy = self.pool.get('training.subscription.line')
+#        tsl_ids = tsl_proxy.search(cr, uid,
+#                                   [
+#                                       ('state', 'not in', ('draft', 'cancelled')),
+#                                       ('date', '>=', "%s 00:00:00" % (date_start)),
+#                                       ('date', '<=', "%s 23:59:59" % (date_stop)),
+#                                       ('kind', '=', 'exam'),
+#                                   ],
+#                                   context=context)
+#
+#        product_lines = {}
+#        for sl in tsl_proxy.browse(cr, uid, tsl_ids, context=context):
+#            if not (sl.course_id and sl.course_id.category_id):
+#                continue
+#            product_line_id = sl.course_id.category_id
+#            product_lines.setdefaults(product_line_id, [])
+#            if sl.invoice_line_id and sl.invoice_id:
+#                product_lines[product_line_id].append(sl)
+#        return True
+
+    def compute_product_lines(self, cr, uid, ids, date_start, date_stop, kind, context=None):
+        if context is None:
+            context = {}
+        res = []
+        tsl_proxy = self.pool.get('training.subscription.line')
+        tsl_ids = tsl_proxy.search(cr, uid,
+                                   [
+                                       ('state', 'not in', ('draft', 'cancelled')),
+                                       ('date', '>=', "%s 00:00:00" % (date_start)),
+                                       ('date', '<=', "%s 23:59:59" % (date_stop)),
+                                       ('kind', '=', kind),
+                                   ],
+                                   context=context)
+        product_lines = {}
+        for sl in tsl_proxy.browse(cr, uid, tsl_ids, context=context):
+            session_id = sl.session_id
+            invoice_id = sl.invoice_id
+            product_line_id = sl.session_id.offer_id.product_line_id
+            product_lines.setdefault(product_line_id,
+                                     {
+                                         'invoices' : set(),
+                                         'sessions' : {},
+                                         'subscription_count' : 0,
+                                         'exams' : {},
+                                     })
+            product_lines[product_line_id]['subscription_count'] += 1
+
+            if invoice_id and sl.invoice_line_id:
+                product_lines[product_line_id]['invoices'].add(invoice_id)
+
+            if sl.session_id not in product_lines[product_line_id]['sessions']:
+
+                po_pool = self.pool.get('purchase.order')
+                sl_sess_seance_ids = [ seance.id for seance in session_id.seance_ids ]
+                sl_sess_po = po_pool.search(cr, uid, [('seance_id','in',sl_sess_seance_ids)], context=context)
+                value = sum(po.invoice_id and po.invoice_id.amount_untaxed or po.amount_untaxed
+                            for po in po_pool.browse(cr, uid, sl_sess_po, context=context))
+                #value = sum(po.procurement_id.purchase_id.amount_total
+                #            for seance in session_id.seance_ids
+                #            for po in seance.purchase_line_ids
+                #            if po.procurement_id and po.procurement_id.purchase_id)
+
+                value += sum(request.purchase_order_id.amount_untaxed
+                             for request in session_id.request_ids
+                             if request.purchase_order_id and request.state in ('accepted', 'done'))
+
+                product_lines[product_line_id]['sessions'][sl.session_id] = value
+
+            if sl.kind == 'exam' and sl.course_id and sl.course_id.category_id:
+                product_lines[product_line_id]['exams'].setdefault(sl.course_id.category_id, {'subscription_count' : 0,
+                                                                                              'price' : 0.0,
+                                                                                             })
+                product_line = product_lines[product_line_id]['exams'][sl.course_id.category_id]
+                product_line['subscription_count'] += 1
+                product_line['price'] += sl.price
+
+        for pl, data in product_lines.iteritems():
+            subscription_count = data['subscription_count']
+            pl_input = sum(invoice_id.amount_untaxed for invoice_id in data['invoices'])
+            pl_output = sum( data['sessions'].values() or [0.0])
+            pl_balance = pl_input - pl_output
+            pl_margin = (pl_input / (pl_output or 1.0)) * 100
+            pl_average_price = subscription_count > 0 and (pl_input / subscription_count) or 0
+            pl_yield = subscription_count > 0 and (pl_balance / subscription_count) or 0
+
+            if ((-0.00001 < pl_input < 0.00001) or (-0.00001 < pl_output < 0.00001)):
+                pl_margin = _('N/A')
+
+            values = {
+                'id' : pl.id,
+                'name' : pl.name,
+                'input' : pl_input,
+                'output' : pl_output,
+                'balance' : pl_balance,
+                'subscription_count' : subscription_count,
+                'margin' : pl_margin,
+                'average_price' : pl_average_price,
+                'yield' : pl_yield,
+                'exams' : [(category.name, vals['subscription_count'], vals['price']) for category, vals in data['exams'].iteritems()]
+            }
+
+            res.append(values)
 
         values = {
-            'id' : pl.id,
-            'name' : pl.name,
-            'input' : pl_input,
-            'output' : pl_output,
-            'balance' : pl_balance,
-            'subscription_count' : subscription_count,
-            'margin' : pl_margin,
-            'average_price' : pl_average_price,
-            'yield' : pl_yield,
-            'exams' : [(category.name, vals['subscription_count'], vals['price']) for category, vals in data['exams'].iteritems()]
-        }
-
-        res.append(values)
-
-    values = {
-        'subscription' : sum(line['subscription_count'] for line in res),
-        'input' : sum(line['input'] for line in res),
-        'output' : sum(line['output'] for line in res),
-    }
-
-    values['balance'] = values['input'] - values['output']
-    if (-0.00001 < values['input'] < 0.00001) or (-0.00001 < values['output'] < 0.00001):
-        values['margin'] = _('N/A')
-    else:
-        values['margin'] = (values['input'] / (values['output'] or 1.0)) * 100.0
-    values['average_price'] = values['subscription'] > 0 and (values['input'] / values['subscription']) or 0
-    values['yield'] = values['subscription'] > 0 and (values['balance'] / values['subscription']) or 0
-
-    return {
-        'product_lines' : res,
-        'total' : values,
-        'date_start' : date_start,
-        'date_stop' : date_stop,
-        'kind' : kind,
-    }
-
-def compute_sessions(cr, uid, ids, context, date_start, date_stop):
-    return {
-        'lines' : [],
-        'date_start' : date_start,
-        'date_stop' : date_stop,
-    }
-
-def compute_subscrtiption_partner(cr, uid, ids, context, date_start, date_stop):
-    cr.execute("""
-               SELECT res.name, coalesce(sum(tsl.price), 0.0) as total_price
-               FROM training_subscription_line tsl,
-                    res_partner res,
-                    training_session s
-               WHERE res.id = tsl.partner_id
-                 AND tsl.session_id = s.id
-               AND tsl.state IN ('confirmed', 'done')
-               AND s.date BETWEEN %s AND %s
-               GROUP BY tsl.partner_id,res.name
-               ORDER BY total_price DESC
-               """, (date_start, date_stop))
-
-    return {
-        'lines' : [{'name' : name, 'price' : price} for name, price in cr.fetchall()],
-        'date_start' : date_start,
-        'date_stop' : date_stop,
-    }
-
-def compute_count_subscriptions_offer(cr, uid, ids, context, date_start, date_stop):
-    return {
-        'lines' : [],
-        'date_start' : date_start,
-        'date_stop' : date_stop,
-    }
-
-def _select(self, cr, uid, data, context=None):
-    functions = {
-        'sessions' : compute_sessions,
-        'count_subscriptions_offer' : compute_count_subscriptions_offer,
-        'subscriptions_partner' : compute_subscrtiption_partner,
-    }
-
-    date_start = data['form']['date_start']
-    date_stop = data['form']['date_stop']
-
-    old_date_start, old_date_stop = previous_period(date_start, date_stop, data['form']['year'])
-
-    old_date_start = old_date_start.strftime('%Y-%m-%d')
-    old_date_stop = old_date_stop.strftime('%Y-%m-%d')
-
-    if data['form']['kind'] == 'product_lines':
-        for kind in ('standard', 'exam', 'intra'):
-            data['form']['selected_period_%s' % kind] = compute_product_lines(cr, uid, data, context, date_start, date_stop, kind)
-            data['form']['old_period_%s' % kind] = compute_product_lines(cr, uid, data, context, old_date_start, old_date_stop, kind)
-    elif data['form']['kind'] == 'theoretical_product_lines':
-        for kind in ('standard', 'exam', 'intra'):
-            data['form']['selected_period_%s' % kind] = compute_theoretical_product_lines(cr, uid, data, context, date_start, date_stop, kind)
-    else:
-        function = functions[data['form']['kind']]
-        data['form']['selected_period'] = function(cr, uid, data, context, date_start, date_stop)
-        data['form']['old_period'] = function(cr, uid, data, context, old_date_start, old_date_stop)
-
-    print(">>> _select :: got dataz" % (data))
-    return data['form']
-
-class wizard_report(wizard.interface):
-    def _select_report(self, cr, uid, data, context=None):
-        return "report_%s" % (data['form']['kind'],)
-
-    states = {
-        'init': {
-            'result': {'type':'form',
-                       'arch':_aged_trial_form,
-                       'fields':_aged_trial_fields,
-                       'state':[('end','Cancel'),('choice','Print')]},
-        },
-        'choice' : {
-            'actions' : [],
-            'result' : { 'type' : 'choice', 'next_state' : _select_report },
-        },
-        'report_product_lines': {
-            'actions': [_select],
-            'result': {'type' : 'print',
-                       'report' : 'training.session.volume',
-                       'state' : 'end'},
-        },
-        'report_theoretical_product_lines': {
-            'actions': [_select],
-            'result': {
-                'type': 'print',
-                'report': 'training.session.volume.theoretical',
-                'state': 'end',
-            },
-        },
-        'report_sessions' : {
-            'actions' : [_select],
-            'result' : {
-                'type' : 'print',
-                'report' : 'training.session.report',
-                'state' : 'end',
-            },
-        },
-        'report_count_subscriptions_offer' : {
-            'actions' : [_select],
-            'result' : {
-                'type' : 'print',
-                'report' : 'training.count.subscriptions.offer',
-                'state' : 'end',
-            },
-        },
-        'report_subscriptions_partner' : {
-            'actions' : [_select],
-            'result' : {
-                'type' : 'print',
-                'report' : 'training.subscriptions.partner',
-                'state' : 'end',
-            }}
-    }
-
-wizard_report('training.session.volume.report')
+            'subscription' : sum(line['subscription_count'] for line in res),
+            'input' : sum(line['input'] for line in res),
+            'output' : sum(line['output'] for line in res),
+        }
+
+        values['balance'] = values['input'] - values['output']
+        if (-0.00001 < values['input'] < 0.00001) or (-0.00001 < values['output'] < 0.00001):
+            values['margin'] = _('N/A')
+        else:
+            values['margin'] = (values['input'] / (values['output'] or 1.0)) * 100.0
+        values['average_price'] = values['subscription'] > 0 and (values['input'] / values['subscription']) or 0
+        values['yield'] = values['subscription'] > 0 and (values['balance'] / values['subscription']) or 0
+
+        return {
+            'product_lines' : res,
+            'total' : values,
+            'date_start' : date_start,
+            'date_stop' : date_stop,
+            'kind' : kind,
+        }
+
+    def compute_sessions(self, cr, uid, ids, date_start, date_stop, context):
+        return {
+            'lines' : [],
+            'date_start' : date_start,
+            'date_stop' : date_stop,
+        }
+
+    def compute_subscrtiption_partner(self, cr, uid, ids, date_start, date_stop, context):
+        cr.execute("""
+                   SELECT res.name, coalesce(sum(tsl.price), 0.0) as total_price
+                   FROM training_subscription_line tsl,
+                        res_partner res,
+                        training_session s
+                   WHERE res.id = tsl.partner_id
+                     AND tsl.session_id = s.id
+                   AND tsl.state IN ('confirmed', 'done')
+                   AND s.date BETWEEN %s AND %s
+                   GROUP BY tsl.partner_id,res.name
+                   ORDER BY total_price DESC
+                   """, (date_start, date_stop))
+
+        return {
+            'lines' : [{'name' : name, 'price' : price} for name, price in cr.fetchall()],
+            'date_start' : date_start,
+            'date_stop' : date_stop,
+        }
+
+    def compute_count_subscriptions_offer(self, cr, uid, ids, date_start, date_stop, context):
+        return {
+            'lines' : [],
+            'date_start' : date_start,
+            'date_stop' : date_stop,
+        }
+
+    def _select(self, cr, uid, data, context=None):
+        if context is None:
+            context = {}
+        functions = {
+            'sessions' : self.compute_sessions,
+            'count_subscriptions_offer' : self.compute_count_subscriptions_offer,
+            'subscriptions_partner' : self.compute_subscrtiption_partner,
+        }
+
+        date_start = data['form']['date_start']
+        date_stop = data['form']['date_stop']
+
+        old_date_start, old_date_stop = self.previous_period(cr, uid, date_start, date_stop, data['form']['year'], context)
+
+        old_date_start = old_date_start.strftime('%Y-%m-%d')
+        old_date_stop = old_date_stop.strftime('%Y-%m-%d')
+
+        if data['form']['kind'] == 'product_lines':
+            for kind in ('standard', 'exam', 'intra'):
+                data['form']['selected_period_%s' % kind] = self.compute_product_lines(cr, uid, data, date_start, date_stop, kind, context)
+                data['form']['old_period_%s' % kind] = self.compute_product_lines(cr, uid, data, old_date_start, old_date_stop, kind, context)
+        elif data['form']['kind'] == 'theoretical_product_lines':
+            for kind in ('standard', 'exam', 'intra'):
+                data['form']['selected_period_%s' % kind] = self.compute_theoretical_product_lines(cr, uid, data, date_start, date_stop, kind, context)
+        else:
+            function = functions[data['form']['kind']]
+            data['form']['selected_period'] = function(cr, uid, data, date_start, date_stop, context)
+            data['form']['old_period'] = function(cr, uid, data, old_date_start, old_date_stop, context)
+
+        return data['form']
+
+    def action_print(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        datas = {'form':{}, 'ids': context.get('active_ids', [])}
+        res = self.read(cr, uid, ids, ['date_start', 'date_stop', 'year', 'kind'], context)
+        res = res and res[0] or {}
+        datas['form'].update(res)
+
+        report_name = False
+        if res.get('kind',False) == 'product_lines':
+            report_name = 'training.session.volume'
+        elif res.get('kind',False) == 'theoretical_product_lines':
+            report_name = 'training.session.volume.theoretical'
+        elif res.get('kind',False) == 'sessions':
+            report_name = 'training.session.report'
+        elif res.get('kind',False) == 'count_subscriptions_offer':
+            report_name = 'training.count.subscriptions.offer'
+        elif res.get('kind',False) == 'subscriptions_partner':
+            report_name = 'training.subscriptions.partner'
+        if not report_name:
+            return {}
+
+        new_datas = self._select(cr, uid, datas, context)
+        datas['form'].update(new_datas)
+        return {
+            'type': 'ir.actions.report.xml',
+            'report_name': report_name,
+            'datas': datas,
+        }
+
+training_report_session_volume()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'training_report/wizard/training_report_session_volume_view.xml'
--- training_report/wizard/training_report_session_volume_view.xml	1970-01-01 00:00:00 +0000
+++ training_report/wizard/training_report_session_volume_view.xml	2011-03-17 10:37:29 +0000
@@ -0,0 +1,37 @@
+<openerp>
+    <data>
+
+        <record model="ir.ui.view" id="view_training_report_session_volume_form">
+            <field name="name">training.report.session.volume.form</field>
+            <field name="model">training.report.session.volume</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Session Volume Report">
+					<separator string="Period" colspan="4" />
+					<field name="date_start"/>
+					<field name="date_stop"/>
+					<separator string="Year" colspan="4" />
+					<field name="year" />
+					<separator string="Report" colspan="4" />
+					<field name="kind" />
+                    <separator colspan="4" />
+                    <group colspan="4" col="2">
+                        <button string="Cancel" special="cancel" type="object" icon="gtk-cancel"/>
+                        <button name="action_print" string="Print" type="object" icon="gtk-print"/>
+                    </group>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="action_training_report_session_volume_form_act">
+            <field name="name">Report Volume</field>
+            <field name="res_model">training.report.session.volume</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <menuitem id="training_report_volume_mi" parent="menu_training_report" action="action_training_report_session_volume_form_act"/>
+
+    </data>
+</openerp>


Follow ups