openerp-dev-web team mailing list archive
-
openerp-dev-web team
-
Mailing list archive
-
Message #04284
[Merge] lp:~openerp-dev/openobject-addons/addons-training-exam-ysa into lp:~openobject-training/openobject-addons/training_with_history
Yogesh(Open ERP) has proposed merging lp:~openerp-dev/openobject-addons/addons-training-exam-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-exam-ysa/+merge/53757
training_exam :- convert into v6.
--
https://code.launchpad.net/~openerp-dev/openobject-addons/addons-training-exam-ysa/+merge/53757
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-addons/addons-training-exam-ysa.
=== modified file 'training_exam/__init__.py'
--- training_exam/__init__.py 2011-02-25 12:33:02 +0000
+++ training_exam/__init__.py 2011-03-17 09:09:48 +0000
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
############################################################################################
#
-# OpenERP, Open Source Management Solution
+# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
@@ -26,3 +26,5 @@
import report
import wizard
import training_content_review_i
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== renamed file 'training_exam/__terp__.py' => 'training_exam/__openerp__.py'
--- training_exam/__terp__.py 2011-02-25 12:33:02 +0000
+++ training_exam/__openerp__.py 2011-03-17 09:09:48 +0000
@@ -40,17 +40,25 @@
#'training_exam_demo.xml',
],
'update_xml' : [
- 'wizard/wizard_deprecate_question_view.xml',
+ 'wizard/training_exam_depricate_question_view.xml',
+ 'wizard/training_exam_question_assign_course_view.xml',
+ 'wizard/training_exam_add_question_view.xml',
'security/training_exam_security.xml',
'security/ir.model.access.csv',
+ 'wizard/training_exam_question_validate_view.xml',
+ 'wizard/training_exam_question_create_new_version_view.xml',
+ 'wizard/training_exam_questionnaire_create_new_version_view.xml',
'training_exam_view.xml',
'training_exam_report.xml',
'workflow/questionnaire_workflow.xml',
'training_exam_sequence.xml',
- 'training_exam_wizard.xml',
'training_content_review_view_i.xml',
- 'wizard/wizard_print_raw_questionnaire_view.xml',
- 'wizard/wizard_validate_question_view.xml',
+ 'wizard/training_exam_print_questionnaire_raw_view.xml',
+ 'wizard/training_exam_validate_question_view.xml',
+ 'wizard/training_seance_generate_view.xml',
+ 'wizard/training_seance_generate_view.xml',
+ 'wizard/training_exam_question_view.xml',
+ 'wizard/training_exam_questionnaire_view.xml',
],
'active' : False,
'installable' : True,
=== modified file 'training_exam/training_content_review_i.py'
--- training_exam/training_content_review_i.py 2011-01-10 11:51:55 +0000
+++ training_exam/training_content_review_i.py 2011-03-17 09:09:48 +0000
@@ -36,6 +36,8 @@
date for the current 'review_record' object
@return string (the SQL query with)
"""
+ if context is None:
+ context = {}
if review_record.reason_id.type == 'exam_material':
return """
SELECT tcr.id,min(tsea.date) AS min_ready_date
@@ -51,12 +53,15 @@
AND tcr.id = %s GROUP BY tcr.id
"""
return super(training_content_review, self)._seance_next_date_query_get(cr, uid, review_record, context=context)
+
training_content_review()
class training_content_review_line(osv.osv):
_inherit = 'training.content.review.line'
def _get_document_name_by_type(self, cr, uid, review_line, context=None):
+ if context is None:
+ context = {}
if review_line.review_id.type == 'exam_material':
return review_line.question_id.name_get()[0][1]
return super(training_content_review_line, self)._get_document_name_by_type(cr, uid, review_line, context=context)
@@ -64,4 +69,7 @@
_columns = {
'question_id': fields.many2one('training.exam.question', 'Question'),
}
+
training_content_review_line()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'training_exam/training_exam.py'
--- training_exam/training_exam.py 2011-02-25 12:33:02 +0000
+++ training_exam/training_exam.py 2011-03-17 09:09:48 +0000
@@ -22,7 +22,8 @@
#
############################################################################################
-from osv import osv, fields
+from osv import osv
+from osv import fields
import netsvc
import random
import datetime
@@ -30,7 +31,6 @@
from tools.translate import _
import time
import os
-import pooler
from training.training import training_course_kind_compute
FMT = '%Y-%m-%d %H:%M:%S'
@@ -59,8 +59,10 @@
_inherit = 'training.session'
def _create_seance(self, cr, uid, session, context=None):
+ if context is None:
+ context = {}
+ group_proxy = self.pool.get('training.group')
if session.kind == 'exam':
- group_proxy = self.pool.get('training.group')
group_ids = group_proxy.search(cr, uid, [('session_id', '=', session.id)])
if group_ids:
group_id = group_ids[0]
@@ -89,18 +91,15 @@
_inherit = 'training.seance'
_columns = {
- 'kind' : fields.selection(
- training_course_kind_compute,
- 'Kind',
- required=True,
- select=1,
- ),
+ 'kind' : fields.selection(training_course_kind_compute, 'Kind', required=True),
}
def _create_participation(self, cr, uid, seance, subscription_line, context=None):
+ if context is None:
+ context = {}
participation = super(training_seance, self)._create_participation(cr, uid, seance, subscription_line, context)
- t_part_proxy = self.pool.get('training.participation')
+ training_participat_pool = self.pool.get('training.participation')
if subscription_line.session_id.kind == 'exam':
# for exam session, we must have a course_id on the subscription line
@@ -108,52 +107,50 @@
raise osv.except_osv(_('Warning'),
_('You have selected an exam seance but there is no associated course'))
vals = {'course_questionnaire_id': subscription_line.course_id.id}
- ocv = t_part_proxy.on_change_course_questionnaire(cr, uid, [], vals['course_questionnaire_id'], False, context=context)
- vals.update(ocv.get('value',{}))
- t_part_proxy.write(cr, uid, [participation], vals)
+ result = training_participat_pool.on_change_course_questionnaire(cr, uid, [], vals['course_questionnaire_id'], False, context=context)
+ vals.update(result.get('value',{}))
+ training_participat_pool.write(cr, uid, [participation], vals)
elif seance.kind == 'exam':
# subscription is not on a exam session, but this seance is an exam
# so the exam participation with be taken on course from this seance
vals = {'course_questionnaire_id': seance.course_id.id}
- ocv = t_part_proxy.on_change_course_questionnaire(cr, uid, [], vals['course_questionnaire_id'], False, context=context)
- vals.update(ocv.get('value',{}))
- t_part_proxy.write(cr, uid, [participation], vals)
+ result = training_participat_pool.on_change_course_questionnaire(cr, uid, [], vals['course_questionnaire_id'], False, context=context)
+ vals.update(result.get('value',{}))
+ training_participat_pool.write(cr, uid, [participation], vals)
return participation
def action_create_procurements(self, cr, uid, ids, context=None):
if not ids:
return False
-
+ if context is None:
+ context = {}
wf_service = netsvc.LocalService("workflow")
-
# For each seance, we will create a procurement for each product
for seance in self.browse(cr, uid, ids, context=context):
if seance.kind == 'exam':
continue
else:
super(training_seance, self).action_create_procurements(cr, uid, [seance.id], context=context)
-
return True
-
def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
+ if context is None:
+ context = {}
request_session_id = context and context.get('request_session_id', False) or False
-
if request_session_id:
session = self.pool.get('training.session').browse(cr, uid, request_session_id, context=context)
-
if session.kind == 'exam':
return [seance.id for seance in session.seance_ids]
-
return super(training_seance, self).search(cr, uid, domain, offset=offset,
limit=limit, order=order, context=context, count=count)
def _get_product(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
assert len(ids) == 1
seance = self.browse(cr, uid, ids[0], context)
-
if seance.kind == 'exam':
# FIXME: Hard coded !!!
product_proxy = self.pool.get('product.product')
@@ -164,6 +161,7 @@
return product_proxy.browse(cr, uid, product_ids[0], context=context)
else:
return super(training_seance, self)._get_product(cr, uid, ids, context=context)
+
training_seance()
class exam_questionnaire(osv.osv):
@@ -178,60 +176,67 @@
# If search is done from the "Add Questions" button on
# "Questionnaires", filter course add to only display courses
# added to this questionnaire
+ if context is None:
+ context = {}
+ questionnarie_pool = self.pool.get('training.exam.questionnaire.course')
if context \
and 'quizz_search' in context \
and 'active_id' in context:
- qc_course_ids = set()
- qc_proxy = self.pool.get('training.exam.questionnaire.course')
- qc_search = [('questionnaire_id','=',context['active_id'])]
- qc_ids = qc_proxy.search(cr, uid, qc_search, context=context)
-
- for qc in qc_proxy.browse(cr, uid, qc_ids):
- qc_course_ids.add(qc.course_id.id)
-
- domain.append(('id','in',list(qc_course_ids)))
+ question_course_ids = set()
+ ques_ids = questionnarie_pool.search(cr, uid, [('questionnaire_id','=',context['active_id'])], context=context)
+ for qc in questionnarie_pool.browse(cr, uid, ques_ids, context):
+ question_course_ids.add(qc.course_id.id)
+
+ domain.append(('id','in',list(question_course_ids)))
return super(training_course, self).search(cr, uid, domain, offset, limit, order, context, count)
def _has_questionnaire_compute(self, cr, uid, ids, fieldnames, args, context=None):
- proxy = self.pool.get('training.exam.questionnaire')
+ if context is None:
+ context = {}
+ tran_exam_questionnar_pool = self.pool.get('training.exam.questionnaire')
res = dict.fromkeys(ids, False)
-
for obj in self.browse(cr, uid, ids, context=context):
- res[obj.id] = len(proxy.search(cr, uid, [('course_id', '=', obj.id),('state', 'in', ('deprecated', 'validated'))], context=context)) > 0
-
+ res[obj.id] = len(tran_exam_questionnar_pool.search(cr, uid, [('main_course_id', '=', obj.id),('state', 'in', ('deprecated', 'validated'))], context=context)) > 0
return res
def _has_valid_questionnaire_compute(self, cr, uid, ids, fieldnames, args, context=None):
- proxy = self.pool.get('training.exam.questionnaire')
+ if context is None:
+ context = {}
+ tran_exam_questionnar_pool = self.pool.get('training.exam.questionnaire')
res = dict.fromkeys(ids, False)
for obj in self.browse(cr, uid, ids, context=context):
- res[obj.id] = len(proxy.search(cr, uid, [('main_course_id', '=', obj.id),('state', '=', 'validated'),('printable','=',True)], context=context)) > 0
-
+ res[obj.id] = len(tran_exam_questionnar_pool.search(cr, uid, [('main_course_id', '=', obj.id),('state', '=', 'validated'),('printable','=',True)], context=context)) > 0
return res
def _get_questionnaires(self, cr, uid, ids, context=None):
- res = set()
+ if context is None:
+ context = {}
+ result = set()
for obj in self.browse(cr, uid, ids, context=context):
if obj.main_course_id:
- res.add(obj.main_course_id.id)
- for c in obj.course_ids:
- res.add(c.course_id.id)
- return list(res)
+ result.add(obj.main_course_id.id)
+ for course in obj.course_ids:
+ result.add(course.course_id.id)
+ return list(result)
def _questionnaire_min_ready_date(self, cr, uid, ids, fieldnames, args, context=None):
+ if context is None:
+ context = {}
now_str = time.strftime('%Y-%m-%d 00:00:00')
- res = dict.fromkeys(ids, '2099-01-01 00:00:00')
+ result = dict.fromkeys(ids, '2099-01-01 00:00:00')
cr.execute("SELECT tp.course_questionnaire_id AS id, min(tp.date) AS date"
" FROM training_participation tp"
" WHERE tp.date >= %s"
" GROUP BY tp.course_questionnaire_id", (now_str,))
for row in cr.dictfetchall():
- res[row['id']] = row['date']
- return res
+ result[row['id']] = row['date']
+ return result
def _questionnaire_min_ready_date_search(self, cr, uid, obj, name, args, context=None):
+ if context is None:
+ context = {}
cmp_op = '='
cmd_date = time.strftime('%Y-%m-%d %H:%M:%S')
for arg in args:
@@ -255,35 +260,21 @@
cr.sql_log = True
cr.execute(cr_query, (cmd_date,))
cr.sql_log = False
- res = set()
+ result = set()
for row in cr.fetchall():
- res.add(row[0])
- return [('id', 'in', list(res))]
+ result.add(row[0])
+ return [('id', 'in', list(result))]
_columns = {
- 'questionnaire_ids' : fields.one2many('training.exam.questionnaire',
- 'main_course_id',
- string='Questionnaire',
- readonly=True),
- 'has_questionnaire' : fields.function(_has_questionnaire_compute,
- method=True,
- string='Has Questionnaires',
- type='boolean',
+ 'questionnaire_ids' : fields.one2many('training.exam.questionnaire', 'main_course_id', string='Questionnaire', readonly=True),
+ 'has_questionnaire' : fields.function(_has_questionnaire_compute, method=True, string='Has Questionnaires', type='boolean',
store= { 'training.exam.questionnaire' : (_get_questionnaires, None, 10) }
),
- 'has_valid_questionnaire': fields.function(_has_valid_questionnaire_compute,
- method=True,
- string='Has Valid Questionnaires',
- type='boolean',
+ 'has_valid_questionnaire': fields.function(_has_valid_questionnaire_compute, method=True, string='Has Valid Questionnaires', type='boolean',
store = { 'training.exam.questionnaire': (_get_questionnaires, None, 10) }
- ),
- 'questionnaire_min_ready_date': fields.function(_questionnaire_min_ready_date,
- type='datetime',
- string='Questionnaire Min Ready Date',
- method=True,
- fnct_search=_questionnaire_min_ready_date_search,
- help='The earliest date on which the course must have a valid questionnaire',
- ),
+ ),
+ 'questionnaire_min_ready_date': fields.function(_questionnaire_min_ready_date, type='datetime', string='Questionnaire Min Ready Date', method=True,
+ fnct_search=_questionnaire_min_ready_date_search, help='The earliest date on which the course must have a valid questionnaire'),
'forced_noquestionnaire': fields.boolean('Forced No Questionnaire', help='This course has no questionnaire, and that is normal', select=2),
'forced_passing_score': fields.float('Forced Passing Score'),
'forced_total_points': fields.float('Forced Total Points'),
@@ -300,11 +291,7 @@
_inherit = 'training.offer'
_columns = {
- 'questionnaire_ids' : fields.many2many('training.course',
- 'training_questionnaire_offer_rel',
- 'offer_id',
- 'questionnaire_id',
- 'Exams',
+ 'questionnaire_ids' : fields.many2many('training.course', 'training_questionnaire_offer_rel', 'offer_id', 'questionnaire_id', 'Exams',
domain=[('has_questionnaire', '=', True)]),
}
@@ -320,31 +307,16 @@
_columns = {
'sequence' : fields.integer('Sequence', required=True),
-
'question_id' : fields.many2one('training.exam.question', 'Question', required=True),
- 'question_type' : fields.related('question_id', 'type',
- type='selection',
+ 'question_type' : fields.related('question_id', 'type', type='selection', string='Type', readonly=True,
selection=[('qcm', 'QCM'),
('qcu', 'QCU'),
('plain', 'Plain'),
- ('yesno', 'Yes/No') ],
- string='Type',
- readonly=True,
+ ('yesno', 'Yes/No')],
),
- 'question_reference': fields.related('question_id', 'reference',
- type='char',
- string='Reference',
- size=32,
- readonly=True),
- 'question_version': fields.related('question_id', 'version',
- type='integer',
- string='Version',
- readonly=True),
- 'question_exposition' : fields.related('question_id', 'question',
- type='text',
- string='Exposition',
- readonly=True),
-
+ 'question_reference': fields.related('question_id', 'reference', type='char', string='Reference', size=32, readonly=True),
+ 'question_version': fields.related('question_id', 'version', type='integer', string='Version', readonly=True),
+ 'question_exposition' : fields.related('question_id', 'question', type='text', string='Exposition', readonly=True),
'questionnaire_id' : fields.many2one('training.exam.questionnaire', 'Questionnaire', required=True, ondelete='cascade'),
}
@@ -352,74 +324,13 @@
training_exam_questionnaire_question()
-class training_exam_question_validate_wizard(osv.osv_memory):
- _name = 'training.exam.question.validate.wizard'
-
- _columns = {
- 'questionnaire_ids': fields.many2many('training.exam.questionnaire', 'training_exam_questionnaire_question_rel', 't1', 't2', 'Questionnaires'),
- 'state': fields.selection([('init', 'Init'),('validate_w_quizz', 'Validate With Quizz'),('validate_wo_quizz', 'Validate Without Quizz')], 'State'),
- }
-
- def _has_questionnaire_validated(self, cr, uid, question_id, context=None):
- qz_pool = self.pool.get('training.exam.questionnaire')
- if not question_id:
- return []
-
- cr.execute("""
- SELECT teqq.questionnaire_id
- FROM training_exam_questionnaire_question teqq
- LEFT JOIN training_exam_question teqn ON (teqq.question_id = teqn.id)
- WHERE teqq.questionnaire_id IN (
- SELECT distinct(questionnaire_id)
- FROM training_exam_questionnaire_question teqq
- WHERE teqq.question_id = %(qid)s)
- GROUP BY teqq.questionnaire_id
- HAVING count(teqn.id) - 1 = sum(CASE WHEN (teqn.state = 'validated' AND teqn.id != %(qid)s) THEN 1 ELSE 0 END)
- """, {'qid': question_id})
-
- qz_ids = [ x[0] for x in cr.fetchall() ]
- return qz_ids
-
- def _get_default_state(self, cr, uid, context=None):
- ids = self._has_questionnaire_validated(cr, uid, context.get('active_id'), context=context)
- if not ids:
- return 'validate_wo_quizz'
- return 'validate_w_quizz'
-
- def _get_default_questionnaire(self, cr, uid, context=None):
- ids = self._has_questionnaire_validated(cr, uid, context.get('active_id'), context=context)
- return ids
-
- def action_validate_wo_qz(self, cr, uid, ids, context=None):
- qid = context.get('active_id')
- if not qid:
- return {}
- self.pool.get('training.exam.question').write(cr, uid, [qid], {'state': 'validated'}, context=context)
- return {}
-
- def action_validate_w_qz(self, cr, uid, ids, context=None):
- wkf = netsvc.LocalService('workflow')
- qid = context.get('active_id')
- if not qid:
- return {}
- self.pool.get('training.exam.question').write(cr, uid, [qid], {'state': 'validated'}, context=context)
- for qwiz in self.browse(cr, uid, ids, context=context):
- for qz in qwiz.questionnaire_ids:
- wkf.trg_validate(uid, 'training.exam.questionnaire', qz.id, 'signal_teq_validate', cr)
- return {}
-
- _defaults = {
- 'state': _get_default_state,
- 'questionnaire_ids': _get_default_questionnaire,
- }
-
-training_exam_question_validate_wizard()
-
class training_question(osv.osv):
_name = 'training.exam.question'
_description = 'Training Exam Question'
def _number_of_good_answer(self, cr, uid, ids, name, args, context=None):
+ if context is None:
+ context = {}
values = dict.fromkeys(ids, 0)
for obj in self.browse(cr, uid, ids, context=None):
if obj.type in ('qcm', 'qcu'):
@@ -430,33 +341,20 @@
return values
_columns = {
- 'name' : fields.char('Name',
- size=128,
- required=True,
- select=1,
- help='Name of Question'),
- 'reference': fields.char('Reference', size=32, required=True,
- readonly=True,
- help='The reference of the question'),
+ 'name' : fields.char('Name', size=128, required=True, select=1, help='Name of Question'),
+ 'reference': fields.char('Reference', size=32, required=True, readonly=True, help='The reference of the question'),
'version': fields.integer('Version', required=True, readonly=True),
- 'question' : fields.text('Question',
- required=True,
- select=1),
- 'is_mandatory' : fields.boolean('Mandatory',
- help='Question is mandatory or not'),
+ 'question' : fields.text('Question', required=True, select=1),
+ 'is_mandatory' : fields.boolean('Mandatory', help='Question is mandatory or not'),
'is_eliminatory' : fields.boolean('Eliminatory'),
'note' : fields.text('Note'),
'type' : fields.selection(
- [('qcm', 'QCM'),
- ('qcu', 'QCU'),
- ('plain', 'Plain'),
- ('yesno', 'Yes/No') ],
- 'Type',
- required=True,
- select=1 ,help='Question type'),
- 'number_of_good_answers' : fields.function(_number_of_good_answer, method=True,
- string='Number of Good Answers',
- type='integer'),
+ [('qcm', 'QCM'),
+ ('qcu', 'QCU'),
+ ('plain', 'Plain'),
+ ('yesno', 'Yes/No') ],
+ 'Type', required=True, select=1 ,help='Question type'),
+ 'number_of_good_answers' : fields.function(_number_of_good_answer, method=True, string='Number of Good Answers', type='integer'),
'response_plain' : fields.text('Solution'),
'response_yesno' : fields.selection([('yes', 'Yes'),('no', 'No')], 'Solution'),
'question_answer_ids' : fields.one2many('training.exam.question.answer', 'question_id', 'Solution'),
@@ -471,14 +369,9 @@
'course_id',
'Courses',
select=1),
- 'point' : fields.float('Point', digits=(12,2),
- required=True,
- help='Point related to question'),
- 'duration': fields.float('Duration',
- required=True,
- help='Time related to question'),
- 'image': fields.binary('Image',
- help='Image to be display next to question text'),
+ 'point' : fields.float('Point', digits=(12,2), required=True, help='Point related to question'),
+ 'duration': fields.float('Duration', required=True, help='Time related to question'),
+ 'image': fields.binary('Image', help='Image to be display next to question text'),
'image_position': fields.selection(
[('before_text', 'Before text'),
('after_text', 'After text')],
@@ -486,13 +379,12 @@
),
# plain question
'free_lines_count': fields.integer('Free Lines',help='How many free line available to formulate a response to a plain question'),
-
# states
'state': fields.selection([
- ('draft', 'Draft'),
- ('validated', 'Validated'),
- ('deprecated', 'Deprecated'),
- ], 'State', required=True, readonly=True, select=1),
+ ('draft', 'Draft'),
+ ('validated', 'Validated'),
+ ('deprecated', 'Deprecated'),
+ ], 'State', required=True, readonly=True, select=1),
'review_line_ids': fields.one2many('training.content.review.line', 'question_id', 'Review Lines', readonly=True),
'deprecated_at': fields.datetime('Deprecated At', readonly=True),
@@ -501,30 +393,39 @@
}
def copy_data(self, cr, uid, id, default=None, context=None):
+ if context is None:
+ context = {}
data, trans_data = super(training_question, self).copy_data(cr, uid, id, default=default, context=context)
if data and 'questionnaire_ids' in data:
del data['questionnaire_ids']
return data, trans_data
def action_draft(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'state': 'draft'})
+ self.write(cr, uid, ids, {'state': 'draft'}, context)
+ return True
def action_validate(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'state': 'validated'})
+ self.write(cr, uid, ids, {'state': 'validated'}, context)
+ return True
def action_deprecate(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
vals = {
'state': 'deprecated',
'deprecated_at': time.strftime('%Y-%m-%d %H:%M:%S'),
'deprecated_by': uid,
'deprecated_note': context.get('_deprecated_note', ''),
}
- self.write(cr, uid, ids, vals)
+ self.write(cr, uid, ids, vals, context)
+ return True
def write(self, cr, uid, ids, vals, context=None):
+ if context is None:
+ context = {}
do_vals_validation = False
- for q in self.browse(cr, uid, ids, context=context):
- if q.state == 'validated':
+ for question in self.browse(cr, uid, ids, context=context):
+ if question.state == 'validated':
do_vals_validation = True
break
# let workflow work correctly
@@ -563,18 +464,19 @@
}
def _check_point(self, cr, uid, ids, context=None):
+ if not ids:
+ return False
obj = self.browse(cr, uid, ids[0], context=context)
return obj.point > 0
def _check_answer(self, cr, uid, ids, context=None):
+ if not ids:
+ return False
obj = self.browse(cr, uid, ids[0], context=context)
-
if obj.type == 'qcm' and obj.number_of_good_answers:
return obj.number_of_good_answers >= 2
-
elif obj.type =='qcu':
return obj.number_of_good_answers == 1
-
return True
_constraints = [
@@ -583,6 +485,8 @@
]
def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
+ if context is None:
+ context = {}
course_id = context and context.get('course_id', False) or False
kind = context and context.get('kind', False) or False
without_course = context and context.get('course', False) or False
@@ -622,30 +526,25 @@
domain.append(('id','in',[ x[0] for x in cr.fetchall() ]))
- return super(training_question, self).search(cr,
- uid,
- domain,
- offset=offset,
- limit=limit,
- order=order,
- context=context,
- count=count)
+ return super(training_question, self).search(cr, uid, domain, offset=offset, limit=limit, order=order, context=context, count=count)
def _get_extended_question_infos_elements(self, cr, uid, question, context=None, report_context=None):
"""
@param question: browse_record(training.exam.question, ?)
"""
- res = []
+ if context is None:
+ context = {}
+ result = []
qn_fields = self.fields_get(cr, uid, fields=['type'], context=context)
qn_type = question.type
qn_type_list = [ x[1] for x in qn_fields.get('type', {}).get('selection', []) if x[0] == qn_type ]
if qn_type_list:
- res.append(('type', _('TYPE: %s') % (qn_type_list[0])))
+ result.append(('type', _('TYPE: %s') % (qn_type_list[0])))
if question.course_ids:
if report_context and not report_context.get('force_course_id',False):
course_list = [ c.name for c in question.course_ids ]
- res.append(('courses', _('COURSES: %s') % (', '.join(course_list))))
- return res
+ result.append(('courses', _('COURSES: %s') % (', '.join(course_list))))
+ return result
training_question()
@@ -655,11 +554,7 @@
_columns = {
'name' : fields.text('Solution', required=True, select=1),
'is_solution' : fields.selection([('yes', 'Yes'),('no', 'No')], 'Acceptable Solution', required=True),
- 'question_id' : fields.many2one('training.exam.question',
- 'Question',
- select=True,
- required=True,
- ondelete="cascade"),
+ 'question_id' : fields.many2one('training.exam.question', 'Question', select=True, required=True, ondelete="cascade"),
}
training_question_answer()
@@ -670,6 +565,8 @@
_rec_name = 'course_id'
def f_total_point(self, cr, uid, ids, fn, args, context=None):
+ if context is None:
+ contet = {}
quizz_proxy = self.pool.get('training.exam.questionnaire')
res = dict.fromkeys(ids, 0.0)
@@ -685,46 +582,28 @@
if not len(quizz.question_ids):
# quizz has no question on it
continue
- for q in quizz.question_ids:
- courses = q.question_id.course_ids
+ for questions in quizz.question_ids:
+ courses = questions.question_id.course_ids
# double conversion to avoid duplicate id, in case
# many2many contains duplicate keyse_ids
courses = list(set(courses))
- for c in courses:
+ for course in courses:
try:
- obj_id = course_ids[c.id]
+ obj_id = course_ids[course.id]
except KeyError:
# course is not related to this quizz
continue
- res[obj_id] += q.question_id.point
+ res[obj_id] += questions.question_id.point
return res or 0.0
_columns = {
- 'course_id': fields.many2one('training.course',
- 'Course',
- required=True,
- ondelete="cascade"),
- 'questionnaire_id': fields.many2one('training.exam.questionnaire',
- 'Questionnaire',
- required=True,
- ondelete='cascade'),
- 'category_id': fields.related('course_id', 'category_id',
- type='many2one',
- relation='training.course_category',
- string='Category of Course',
- readonly=True),
- 'kind': fields.related('course_id', 'kind',
- type='selection',
- selection=training_course_kind_compute,
- string='Kind',
- readonly=True),
- 'passing_score': fields.float('Passing Score',
- required=True,
- help='Passing score of related to Exam'),
- 'total_point': fields.function(f_total_point,
- method=True,
- type='float',
- string='Total Point'),
+ 'course_id': fields.many2one('training.course', 'Course', required=True, ondelete="cascade"),
+ 'questionnaire_id': fields.many2one('training.exam.questionnaire', 'Questionnaire', required=True, ondelete='cascade'),
+ 'category_id': fields.related('course_id', 'category_id', type='many2one', relation='training.course_category',
+ string='Category of Course', readonly=True),
+ 'kind': fields.related('course_id', 'kind', type='selection', selection=training_course_kind_compute, string='Kind', readonly=True),
+ 'passing_score': fields.float('Passing Score', required=True, help='Passing score of related to Exam'),
+ 'total_point': fields.function(f_total_point, method=True, type='float', string='Total Point'),
}
_defaults = {
@@ -732,6 +611,8 @@
}
def on_change_course(self, cr, uid, ids, course_id, context=None):
+ if context is None:
+ context = {}
if not course_id:
return {'value' : {'category_id':''}}
course = self.pool.get('training.course').browse(cr,uid,course_id)
@@ -745,7 +626,7 @@
_description = 'Training Exam Questionnaire'
def copy_data(self, cr, uid, object_id, values=None, context=None):
- if not context:
+ if context is None:
context = {}
if not values:
values = {}
@@ -755,33 +636,38 @@
return super(exam_questionnaire, self).copy_data(cr, uid, object_id, values, context=context)
def _func_get_type(self, cr, uid, ids, name, args, context=None):
- r = {}
+ if context is None:
+ context = {}
+ result = {}
for quizz in self.browse(cr, uid, ids):
type = 'automatic'
- for q in quizz.question_ids:
- if q.question_type == 'plain':
+ for question in quizz.question_ids:
+ if question.question_type == 'plain':
type = 'manual'
break
- r[quizz.id] = type
- return r
+ result[quizz.id] = type
+ return result
def _get_quizz_from_quizz_lines(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
if not ids:
return []
quizzes = set()
- for quizz_line in self.read(cr, uid, ids, ['questionnaire_id']):
- quizzes.add(quizz_line['questionnaire_id'][0])
+ for quizz_line in self.read(cr, uid, ids, ['questionnaire_id'], context=context):
+ quizzes.add(quizz_line['questionnaire_id'] and quizz_line['questionnaire_id'][0])
return quizzes
def _get_quizz_from_questions(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
if not ids:
return []
pool_quizz_q = self.pool.get('training.exam.questionnaire.question')
- quizz_lines = set()
quizzes = set()
quizz_lines = pool_quizz_q.search(cr, uid, [('question_id','in',ids)])
- for quizz_line in pool_quizz_q.read(cr, uid, quizz_lines, ['questionnaire_id']):
- quizzes.add(quizz_line['questionnaire_id'][0])
+ for quizz_line in pool_quizz_q.read(cr, uid, quizz_lines, ['questionnaire_id'], context=context):
+ quizzes.add(quizz_line['questionnaire_id'] and quizz_line['questionnaire_id'][0])
return quizzes
def _len_question_ids(self, cr, uid, ids, field_name, value, context=None):
@@ -801,13 +687,16 @@
return res or 0.0
def course_category(self, cr, uid, ids, name, args, context=None):
+ if context is None:
+ context = {}
coursecat_proxy = self.pool.get('training.course_category')
res = dict.fromkeys(ids, '')
for obj in self.browse(cr,uid,ids,context=context):
results = []
for course in obj.course_ids:
result = coursecat_proxy.search(cr, uid, [('analytic_account_id','=',course.course_id.parent_id.id)], context=context)
- results.append(result[0])
+ if result:
+ results.append(result[0])
# only keep the first reference (exam quizz should only have
# one course attached, for other don't specify product line
# to avoid errors
@@ -822,6 +711,8 @@
The global passing score is the sum of all passing score by
courses
"""
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, '')
for obj in self.browse(cr, uid, ids, context=context):
if not obj.course_ids:
@@ -832,6 +723,8 @@
return res or 0.0
def _is_printable(self, cr, uid, ids, fn, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, True)
disabled_ids = self._search_is_printable(cr, uid, ids, '', [('printable', '=', False)])[0][2]
for id in disabled_ids:
@@ -839,6 +732,8 @@
return res
def _search_is_printable(self, cr, uid, ids, fn, args, context=None):
+ if context is None:
+ context = {}
op = 'not in'
for a in args:
if a[0] == 'printable':
@@ -867,78 +762,39 @@
_columns = {
'name' : fields.char( 'Name', size=128, required=True, select=1 ,help='Name of questionnaire'),
- 'reference': fields.char('Reference', size=32, select=1, required=True,
- readonly=True,
- help='Reference number of the questionnaire'),
+ 'reference': fields.char('Reference', size=32, select=1, required=True, readonly=True, help='Reference number of the questionnaire'),
'version': fields.integer('Version', required=True, readonly=True),
'state' : fields.selection([('draft', 'Draft'),
('validated', 'Validated'),
('deprecated', 'Deprecated')
],
- 'State',
- required=True,
- readonly=True,
- select=1,
- help='The state of the Questionnaire'),
- 'kind': fields.function(_func_get_type, method=True,
- type='selection',
- string='Mode',
+ 'State', required=True, readonly=True, select=1, help='The state of the Questionnaire'),
+ 'kind': fields.function(_func_get_type, method=True, type='selection', string='Mode',
selection=[('automatic','Automatic'),
('manual','Manual')],
store={
'training.exam.questionnaire.question': (_get_quizz_from_quizz_lines, [], 0),
'training.exam.question': (_get_quizz_from_questions, ['type'], 0),
},
- select=1,
- help='How this questionnaire could be corrected'),
- 'type': fields.selection([('examen', 'Examen')],
- 'Type',
- required=True,
- select=2),
+ select=1, help='How this questionnaire could be corrected'),
+ 'type': fields.selection([('examen', 'Examen')], 'Type', required=True, select=2),
'objective' : fields.text('Objective'),
'description' : fields.text('Description'),
'remark_firstpage': fields.text('Remark First Page'),
-
- 'main_course_id' : fields.many2one('training.course',
- 'Main Course',
- required=True,
- select=1,
- domain="[('state_course', 'in', ('draft', 'validated', 'pending'))]",
- ondelete='restrict'),
+ 'main_course_id' : fields.many2one('training.course', 'Main Course', required=True, select=1, ondelete='restrict',
+ domain="[('state_course', 'in', ('draft', 'validated', 'pending'))]"),
'questionnaire_min_ready_date': fields.related('main_course_id', 'questionnaire_min_ready_date',
type='datetime', string='Questionnaire Min Ready Date', readonly=True),
-
- 'course_ids': fields.one2many('training.exam.questionnaire.course',
- 'questionnaire_id',
- string='Courses'),
-
- 'total_point' : fields.function(point_compute,method=True,
- type='float',
- string='Total Point',
- help='Total point for the questionnaire'),
- 'duration' : fields.function(duration_compute,method=True,
- type='float',
- string='Duration',
- help='Duration for the exam'),
+ 'course_ids': fields.one2many('training.exam.questionnaire.course', 'questionnaire_id', string='Courses'),
+ 'total_point' : fields.function(point_compute,method=True, type='float', string='Total Point', help='Total point for the questionnaire'),
+ 'duration' : fields.function(duration_compute,method=True, type='float', string='Duration', help='Duration for the exam'),
'question_ids' : fields.one2many('training.exam.questionnaire.question', 'questionnaire_id', 'Questions'),
- 'len_question_ids' : fields.function(_len_question_ids,
- method=True,
- type='integer',
- string='Number of Questions',
+ 'len_question_ids' : fields.function(_len_question_ids, method=True, type='integer', string='Number of Questions',
help='Total number of questions'),
- 'passing_score': fields.function(f_passing_score,
- method=True,
- type='float',
- string='Global Passing Score',
+ 'passing_score': fields.function(f_passing_score, method=True, type='float', string='Global Passing Score',
help='The global passing score of the questionnaire'),
-
- 'category' : fields.function(course_category,
- method=True,
- type='many2one',
- relation='training.course_category',
- string='Category of Course',
- select=1,
- ),
+ 'category' : fields.function(course_category, method=True, type='many2one', relation='training.course_category',
+ string='Category of Course', select=1),
'attachment_ids': fields.one2many('training.exam.questionnaire.attachment', 'questionnaire_id', 'Attachments',),
'forced_noprint': fields.boolean('Forced No Print', help='Check this to avoid choosing this questionnaire when assigning it to the participation', select=2),
'printable': fields.function(_is_printable, fnct_search=_search_is_printable, type='boolean', method=True,
@@ -963,6 +819,8 @@
}
def _check_course_limit(self, cr, uid, ids, context=None):
+ if not ids:
+ return False
obj = self.browse(cr, uid, ids[0], context=None)
if obj.type == 'examen' and len(obj.course_ids) > 1:
return False
@@ -970,6 +828,8 @@
def _check_score(self, cr, uid, ids, context=None):
+ if not ids:
+ return False
obj = self.browse(cr, uid, ids[0], context=context)
return 0.0 <= obj.passing_score <= obj.total_point
@@ -979,8 +839,9 @@
]
def set_pending_status(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
workflow = netsvc.LocalService('workflow')
-
for oid in ids:
cr.execute("SELECT id FROM wkf_instance WHERE res_type = %s AND res_id = %s AND state = 'active'",
(self._name, oid))
@@ -995,11 +856,11 @@
return self.write(cr, uid, ids, {'state' : 'pending'}, context=context)
def reset_to_draft_cb(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
workflow = netsvc.LocalService('workflow')
-
for oid in ids:
workflow.trg_create(uid, self._name, oid, cr)
-
return self.write(cr, uid, ids, {'state' : 'draft'}, context=context)
def wkf_validate(self, cr, uid, ids, context=None):
@@ -1010,126 +871,12 @@
exam_questionnaire()
-class exam_questionnaire_wizard(osv.osv_memory):
- _name = 'training.exam.questionnaire.wizard'
- _description = 'Questionnaire Wizard'
-
- _columns = {
- 'name' : fields.char('Name', size=64, required=True),
- 'course_id' : fields.many2one('training.course', 'Course',
- required=True,
- domain="[('state_course', '=', 'validated')]"),
- 'number_of_question' : fields.integer('Number of Questions'),
- 'kind' : fields.selection(
- [
- ('automatic', 'Automatic'),
- ('manual', 'At Least one open-ended question')
- ],
- 'Type'),
- }
-
- _defaults = {
- 'kind' : lambda *a: 'automatic',
- 'number_of_question' : lambda *a: 20,
- }
-
- def action_cancel(self, cr, uid, ids, context=None):
- return {'type':'ir.actions.act_window_close'}
-
- def action_generate_questionnaire(self, cr, uid, ids, context=None):
- this = self.browse(cr, uid, ids, context=context)[0]
-
- question_proxy = self.pool.get('training.exam.question')
-
- all_question_ids = question_proxy.search(cr, uid, [], context=context)
-
- mandatory_question_ids = []
- question_ids = []
-
- for question in question_proxy.browse(cr, uid, all_question_ids, context=context):
- if this.course_id in question.course_ids:
- if question.is_mandatory:
- mandatory_question_ids.append(question.id)
- else:
- question_ids.append(question.id)
-
- mqids = []
- qids = []
-
- import random
-
- number_of_mandatory_questions = random.randint(0, 3)
- number_of_questions = min(max(20, this.number_of_question) - number_of_mandatory_questions,len(question_ids))
-
- while number_of_mandatory_questions:
- try:
- idx = random.randint(0, len(mandatory_question_ids))
- mqids.append(mandatory_question_ids[idx])
- del mandatory_question_ids[idx]
- except:
- pass
- number_of_mandatory_questions -= 1
-
- while number_of_questions:
- try:
- idx = random.randint(0, len(question_ids))
- qids.append(question_ids[idx])
- del question_ids[idx]
- number_of_questions -= 1
- except:
- pass
-
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'training.exam.questionnaire',
- 'view_id':self.pool.get('ir.ui.view').search(cr,uid,[('name','=','training.exam.questionnaire.form')]),
- 'type': 'ir.actions.act_window',
- 'target':'current',
- 'context' : {
- 'default_name' : this.name,
- 'default_course_id' : this.course_id.id,
- 'default_question_ids' : mqids + qids,
- 'default_kind' : this.kind,
- }
- }
-
-exam_questionnaire_wizard()
-
-class training_question_wizard(osv.osv_memory):
- _name = 'training.exam.question.wizard'
- _description = 'Question Wizard'
-
- _columns = {
- 'course_id' : fields.many2one('training.course', 'Course', required=True,
- domain="[('state_course', '=', 'validated')]"),
- }
-
- def action_cancel(self, cr, uid, ids, context=None):
- return {'type':'ir.actions.act_window_close'}
-
- def find_question_with_course(self, cr, uid, ids, context=None):
- this = self.browse(cr, uid, ids, context=context)[0]
-
- context2 = context.copy()
- context2.update({'course_id':this.course_id.id})
-
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'training.exam.question',
- 'view_id':self.pool.get('ir.ui.view').search(cr,uid,[('name','=','training.exam.question.tree')]),
- 'type': 'ir.actions.act_window',
- 'target':'current',
- 'context': context2,
- }
-
-training_question_wizard()
-
class training_subscription(osv.osv):
_inherit = 'training.subscription'
def action_subscription_line_compute(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
if not len(ids):
return False
@@ -1173,7 +920,6 @@
return True
-
training_subscription()
class training_subscription_line(osv.osv):
@@ -1191,11 +937,15 @@
}
def _check_subscription(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
# FIXME check also the overlaps for exam sessions...
ids = [line.id for line in self.browse(cr, 1, ids, context=context) if line.session_id.kind != 'exam']
return super(training_subscription_line, self)._check_subscription(cr, uid, ids, context)
def on_change_session(self, cr, uid, ids, session_id, price_list_id, partner_id, context=None):
+ if context is None:
+ context = {}
if not session_id:
return False
session = self.pool.get('training.session').browse(cr, uid, session_id, context=context)
@@ -1212,6 +962,8 @@
return res
def on_change_exam(self, cr, uid, ids, session_id, price_list_id, course_id, partner_id, context=None):
+ if context is None:
+ context = {}
# If exam course is from a product line with special members,
# we must apply this pricelist if current partner is one of those
ocv = {'value':{}}
@@ -1233,6 +985,8 @@
return ocv
def on_change_price_list(self, cr, uid, ids, session_id, price_list_id, course_id, context=None):
+ if context is None:
+ context = {}
if not session_id or not price_list_id:
return False
session = self.pool.get('training.session').browse(cr, uid, session_id, context=context)
@@ -1256,6 +1010,8 @@
}
def _get_values_from_wizard(self, cr, uid, subscription_id, job, subscription_mass_line, context=None):
+ if context is None:
+ context = {}
subscription = self.pool.get('training.subscription').browse(cr, uid, subscription_id, context=context)
session = subscription_mass_line.session_id
@@ -1283,6 +1039,8 @@
return values
def _get_courses(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, [])
standard_ids = []
@@ -1300,6 +1058,8 @@
# training.subscription.line
def _get_invoice_line_data(self, cr, uid, name, invoice_id, partner, session, subline, context=None):
+ if context is None:
+ context = {}
values = super(training_subscription_line, self)._get_invoice_line_data(cr, uid, name, invoice_id, partner, session, subline, context=context)
if not values:
values = {}
@@ -1310,6 +1070,8 @@
# training.subscription.line
def _get_invoice_line_taxes(self, cr, uid, subline, fiscal_position, partner, session, context=None):
+ if context is None:
+ context = {}
if subline.kind == 'exam':
_slc = subline.course_id
if _slc:
@@ -1324,12 +1086,14 @@
# training.subscription.line
def action_create_invoice(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
# Creation des factures
account_id = self.pool.get('account.account').search(cr, uid, [('code', '=', '70828')])[0]
# Get journal
- journal_proxy = self.pool.get('account.journal')
- journal_sales_srch = journal_proxy.search(cr, uid, [('type','=','sale'),('refund_journal','=',False)])
- journal_sales = journal_proxy.browse(cr, uid, journal_sales_srch)[0]
+ journal_pool = self.pool.get('account.journal')
+ journal_sales_srch = journal_pool.search(cr, uid, [('type','=','sale'),('refund_journal','=',False)])
+ journal_sales = journal_pool.browse(cr, uid, journal_sales_srch)[0]
proxy_seance = self.pool.get('training.seance')
proxy_invoice = self.pool.get('account.invoice')
@@ -1451,6 +1215,8 @@
_rec_name = 'course_id'
def f_get_score(self, cr, uid, ids, fieldnames, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 0.0)
result_per_part = {}
courses_per_part = {}
@@ -1497,8 +1263,7 @@
'score': fields.function(f_get_score, method=True, type='float', required=True, string='Score', readonly=True),
'max_score': fields.float('Max Score', required=True),
'succeeded': fields.function(f_is_succeeded, method=True, type='selection',
- selection=[('n/a','N/A'),('no','No'),('yes','Yes')],
- string='Succeeded'),
+ selection=[('n/a','N/A'),('no','No'),('yes','Yes')], string='Succeeded'),
'confirmed_by_assessor': fields.boolean('Confirmed by Assessor'),
}
@@ -1511,20 +1276,21 @@
if not values:
values = {}
if 'course_line_ids' not in values:
- values['course_line_ids'] = []
+ values.update({'course_line_ids' : []})
if 'participation_line_ids' not in values:
- values['participation_line_ids'] = []
+ values.update({'participation_line_ids' : []})
return super(training_participation_exam, self).copy_data(cr, uid, object_id, values, context)
def after_exam_sheet_generation(self, cr, uid, participation_id, context=None):
- pool = pooler.get_pool(cr.dbname)
+ if context is None:
+ context = {}
# Need to register questions printed on PDF into corresponding training.participation record
qn = 1 # question number
qset = set() # question id set
qdict = {}
- tpline = pool.get('training.participation.line')
- tpline_current_ids = tpline.search(cr, uid, [('participation_id','=',participation_id)])
+ tpline = self.pool.get('training.participation.line')
+ tpline_current_ids = tpline.search(cr, uid, [('participation_id','=',participation_id)], context=context)
if len(tpline_current_ids) != 0:
raise Exception("Can't generate exam sheet on participation which already have participation line %s" % (participation_id))
@@ -1537,7 +1303,7 @@
'question_id': question_line.question_id.id,
'graded': False,
}
- new_id = tpline.create(cr, uid, new_tpline)
+ new_id = tpline.create(cr, uid, new_tpline, context=context)
qdict[str(question_line.question_id.id)] = new_id
for page_num, page in enumerate(context['checkboxes_context']):
@@ -1557,12 +1323,14 @@
new_tpline.update({
'sequence': new_qn,
})
- new_id = tpline.create(cr, uid, new_tpline)
+ new_id = tpline.create(cr, uid, new_tpline, context=context)
qdict[qid] = new_id
else:
tpline.write(cr, uid, qdict[qid], new_tpline, context=context)
def _result_compute(self, cr, uid, ids, fieldnames, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 0.0)
for p in self.browse(cr, uid, ids, context=context):
if p.forced_result >= -0.001 and p.forced_result <= 0.001:
@@ -1575,6 +1343,8 @@
return res
def _result_pourcentage_compute(self, cr, uid, ids, fieldnames, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 0.0)
for p in self.read(cr, uid, ids, ['result','total_points'], context=context):
if p['total_points'] <= 0.0:
@@ -1584,6 +1354,8 @@
return res
def _total_points_compute(self, cr, uid, ids, fieldnames, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 0.0)
quizz_cache = {}
quizz_proxy = self.pool.get('training.exam.questionnaire')
@@ -1610,6 +1382,8 @@
return res
def _succeeded(self, cr, uid, ids, fn, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 'n/a')
for p in self.browse(cr, uid, ids, context=context):
# if passing_score == 0, that means it's not set!
@@ -1618,6 +1392,8 @@
return res
def _succeeded_search(self, cr, uid, obj, name, args, context=None):
+ if context is None:
+ context = {}
if not args:
return []
# default cond = False
@@ -1646,6 +1422,8 @@
return [('id', 'in', search_ids)]
def _certif_printed(self, cr, uid, ids, name, args, context=None):
+ if context is None:
+ context = {}
res = dict.fromkeys(ids, 0)
q = """
SELECT res_id, count(1)
@@ -1661,6 +1439,8 @@
return res
def _checkstore_update_certif(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
proxy = self.pool.get('ir.attachment')
attach_ids = proxy.search(cr, uid, [('id', 'in', ids),('res_model', '=', 'training.participation'),('name', 'like', 'CERTIF%')], context=context)
res = set()
@@ -1678,6 +1458,8 @@
return {'value': {'result_received': ret_val }}
def on_change_course_questionnaire(self, cr, uid, ids, course_id, questionnaire_id, context=None):
+ if context is None:
+ context = {}
ocv = {'value': {}}
course_pool = self.pool.get('training.course')
quizz_pool = self.pool.get('training.exam.questionnaire')
@@ -1703,6 +1485,8 @@
return ocv
def on_change_questionnaire(self, cr, uid, ids, course_id, questionnaire_id, context=None):
+ if context is None:
+ context = {}
if not questionnaire_id:
return {'value': {
'passing_score': 0.0,
@@ -1752,25 +1536,15 @@
_columns = {
'exam_id': fields.related('subscription_line_id', 'course_id', type='many2one', relation='training.course', readonly=True, string="Exam"),
- 'questionnaire_id' : fields.many2one('training.exam.questionnaire', 'Questionnaire',
- help='Select the Questionnaire for participant'),
+ 'questionnaire_id' : fields.many2one('training.exam.questionnaire', 'Questionnaire', help='Select the Questionnaire for participant'),
'course_questionnaire_id': fields.many2one('training.course', string='Exam', select=1),
- 'duration_questionnaire_id' : fields.related('questionnaire_id',
- 'duration',
- type='float',
- string='Duration',
- store=True,
+ 'duration_questionnaire_id' : fields.related('questionnaire_id', 'duration', type='float', string='Duration', store=True,
readonly=True,help='Duration of selected Questionnaire'),
'kind_questionnaire_id': fields.related('questionnaire_id', 'kind', type='selection', selection=[('automatic','Automatic'),('manual','Manual')], string='Kind of Questionnaires', select=2, readonly=True),
- 'course_line_ids': fields.one2many('training.participation.course.line',
- 'participation_id',
- 'Course Lines'),
- 'participation_line_ids' : fields.one2many('training.participation.line',
- 'participation_id',
- 'Participation Lines'),
+ 'course_line_ids': fields.one2many('training.participation.course.line', 'participation_id', 'Course Lines'),
+ 'participation_line_ids' : fields.one2many('training.participation.line', 'participation_id', 'Participation Lines'),
'result_received': fields.boolean('Result received', select="2"),
- 'forced_result': fields.float('Forced Result', digits=(12,2),
- help='If not zero, this is the score that will be forced'),
+ 'forced_result': fields.float('Forced Result', digits=(12,2), help='If not zero, this is the score that will be forced'),
'forced_noresult': fields.boolean('Forced No Result', help='Check if this participation won\'t have any result, and that is normal. This particaption will not be taken anymore in account for correction request, exam certificate'),
'result' : fields.function(_result_compute, method=True, string='Result', type='float',
store={
@@ -1793,29 +1567,17 @@
),
'result_pourcentage': fields.function(_result_pourcentage_compute, method=True, string='Result (%)', type='float',
help="Exam Result of Participate in Pourcetage"),
- 'passing_score': fields.float('Passing Score',
- help='The minimum score needed to succueed to this exam, assigned when questionnaire is affected to the participation (on "Exam Sheet" generation) and not updated after'),
-
+ 'passing_score': fields.float('Passing Score', help='The minimum score needed to succueed to this exam, assigned when questionnaire is affected to the participation (on "Exam Sheet" generation) and not updated after'),
'kind' : fields.related('seance_id', 'kind', type='selection', selection=[('standard', 'Course'),('exam', 'Exam')], string='Kind', select=1),
- 'succeeded': fields.function(_succeeded,
- fnct_search=_succeeded_search,
- method=True,
- type='selection',
+ 'succeeded': fields.function(_succeeded, fnct_search=_succeeded_search, method=True, type='selection',
selection=[('n/a', 'N/A'),
('no', 'No'),
('yes', 'Yes')],
- select=2,
- string='Succeeded'),
-
- 'certif_printed' : fields.function(_certif_printed,
- method=True,
- type="boolean",
+ select=2, string='Succeeded'),
+ 'certif_printed' : fields.function(_certif_printed, method=True, type="boolean",
store={
'ir.attachment' : (_checkstore_update_certif, None, 10),
- },
- select=2,
- string="Certificate Printed"),
-
+ }, select=2, string="Certificate Printed"),
}
_defaults = {
@@ -1832,39 +1594,27 @@
_columns = {
'sequence': fields.integer('Question N°'),
'page_num': fields.integer('Page N°'),
- 'participation_id' : fields.many2one('training.participation', 'Participation',
- required=True,
- ondelete="cascade"),
+ 'participation_id' : fields.many2one('training.participation', 'Participation', required=True, ondelete="cascade"),
'question_id' : fields.many2one('training.exam.question', 'Question', ondelete='restrict'),
'question_question_id': fields.related('question_id', 'question', type='text', string='Question', readonly=True, help='Exposition of the question'),
'point_question_id' : fields.related('question_id', 'point', type='float', string='Max Point', readonly=True,help='Point of question'),
- 'type_question_id' : fields.related('question_id', 'type',
- type='selection',
+ 'type_question_id' : fields.related('question_id', 'type', type='selection', string='Type', readonly=True,
selection = [('qcm', 'QCM'),
('qcu', 'QCU'),
('plain', 'Plain'),
- ('yesno', 'Yes/No') ],
- string='Type', readonly=True),
- 'yesno_question_id' : fields.related('question_id', 'response_yesno', type='char',
- string='Solution YesNo', readonly=True,help='Question type'),
- 'plain_question_id' : fields.related('question_id', 'response_plain', type='text',
- string='Solution Plain', readonly=True),
- 'qcm_question_id' : fields.related('question_id', 'question_answer_ids', type='one2many',
- relation='training.exam.question.answer', readonly=True,
- string='Solution QCM'),
+ ('yesno', 'Yes/No') ]),
+ 'yesno_question_id' : fields.related('question_id', 'response_yesno', type='char', string='Solution YesNo', readonly=True,help='Question type'),
+ 'plain_question_id' : fields.related('question_id', 'response_plain', type='text', string='Solution Plain', readonly=True),
+ 'qcm_question_id' : fields.related('question_id', 'question_answer_ids', type='one2many', relation='training.exam.question.answer',
+ readonly=True, string='Solution QCM'),
'graded': fields.boolean('Is Graded'),
-
# Response from the user
'response_qcm_ids' : fields.many2many('training.exam.question.answer', 'training_result_line_answer_rel',
'exam_line_id', 'question_answer_id', 'Solutions', domain="[('question_id', '=', question_id)]"),
'response_plain' : fields.text('Solution'),
'response_yesno' : fields.selection([('yes', 'Yes'),('no', 'No')], 'Solution'),
-
- 'point' : fields.float('Point', digits=(12,2),
- help='Number of point get from question'),
-
+ 'point' : fields.float('Point', digits=(12,2), help='Number of point get from question'),
'note' : fields.text('Note'),
-
}
_defaults = {
@@ -1873,61 +1623,31 @@
}
def _check_score(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
obj = self.browse(cr, uid, ids[0], context=context)
question = self.pool.get('training.exam.question').browse(cr, uid, obj.question_id.id)
return obj.point <=question.point or 0.0
+
def on_change_question(self, cr, uid, ids, question_id, context=None):
+ if context is None:
+ context = {}
if not question_id:
return False
-
question = self.pool.get('training.exam.question').browse(cr, uid, question_id)
-
return {
'value': {
'point_question_id': question.point,
'type_question_id' : question.type,
}
}
+
_constraints = [
(_check_score, "Can you check the give point ?", ['point']),
]
+
training_participation_line()
-class mass_subscription_line(osv.osv_memory):
- _inherit = 'training.subscription.mass.line'
-
- _columns = {
- 'date_session' : fields.related('session_id', 'date', type='datetime', string='Date', readonly=True),
- 'exam_session_id' : fields.many2one('training.session', 'Exam Session'),
- 'course_id' : fields.many2one('training.course', 'Exam',
- domain="[('state_course', '=', 'validated')]"),
- }
-
- def on_change_session(self, cr, uid, ids, session_id, context=None):
- if not session_id:
- return False
-
- session = self.pool.get('training.session').browse(cr, uid, session_id)
- dates = [seance.date for seance in session.seance_ids]
-
- return {
- 'value' : {
- 'kind' : session.kind,
- 'date_session' : session.date,
- 'exam_session_id': False,
- 'course_id': False,
- },
- 'domain' : {
- 'exam_session_id' :
- [('state', 'in', ('opened_confirmed', 'opened', 'closed_confirmed')),
- ('kind', '=', 'exam'),
- ('date', '>', len(dates) and max(dates) or session.date),
- ('id', '!=', session.id)],
- },
- }
-
-mass_subscription_line()
-
class training_participation_stakeholder(osv.osv):
_inherit = 'training.participation.stakeholder'
_columns = {
@@ -1940,11 +1660,15 @@
}
def _check_disponibility(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
# FIXME check also the overlaps for exam sessions at different places...
ids = [sh.id for sh in self.browse(cr, uid, ids, context=context) if sh.kind != 'exam']
return super(training_participation_stakeholder, self)._check_disponibility(cr, uid, ids, context)
def _default_price_compute(self, cr, uid, job, seance, product_id=None, context=None):
+ if context is None:
+ context = {}
if not job or not seance:
return False
if isinstance(seance, (int, long)):
@@ -1973,6 +1697,8 @@
}
def _create_from_wizard(self, cr, uid, the_wizard, job, subscription_line_mass, context=None):
+ if context is None:
+ context = {}
proxy = self.pool.get('training.subscription.line.second')
return proxy.create(cr, uid,
{
@@ -2003,122 +1729,9 @@
return DEFAULT_LANG
return subline.course_id.lang_id.code
return super(training_email, self)._get_lang(session, seance, **objects)
+
training_email()
-class training_seance_generate_pdf_wizard(osv.osv_memory):
- _inherit = 'training.seance.generate.zip.wizard'
-
- _columns = {
- 'exams_report' : fields.boolean('Exams',
- help="If you select this option, you will print the exams. The filename format is Exam_DATE_PARTICIPATIONID.pdf"),
- }
-
- _defaults = {
- 'exams_report' : lambda *a: False,
- }
-
-
- def _get_report(self, cr, uid, oid, reportname, context=None, data=None):
- if data is None:
- data = {}
- srv = netsvc.LocalService(reportname)
- pdf, _r = srv.create(cr, uid, [oid], data, context=context)
- return pdf
-
- def add_selections(self, cr, uid, ids, directory, log, context=None):
- active_id = context and context.get('active_id')
- seance = self.pool.get('training.seance').browse(cr, uid, active_id, context=context)
- ts = time.strptime(seance.date, '%Y-%m-%d %H:%M:%S')
- date = time.strftime('%Y%m%d', ts)
-
- exam_directory = os.path.join(directory, 'Exams')
- os.mkdir(exam_directory)
-
- res = []
- for obj in self.browse(cr, uid, ids, context=context):
- if obj.exams_report:
- for i, part in enumerate(seance.participant_ids):
- if part.exam_id.forced_noquestionnaire:
- log.write('ignored participation %d because related exam is marked as: forced no questionnaire\n' % (part.id))
- continue
- try:
- res = self._get_report(cr, uid, part.id, 'report.training.participation.report',
- context=context, data={'model': 'training.participation', 'id': part.id})
- except osv.except_osv, e:
- log.errors += (u'Participation ID: %d got %s\n' % (part.id, e.value))
- continue
- #raise e
-
- filename = os.path.join(exam_directory, 'Exam_%03d_%s_%s_%s_%06d.pdf' % (i, part.contact_lastname, part.contact_firstname, date, part.id))
- fp = file(filename, 'w')
- fp.write(res)
- fp.close()
-
- super(training_seance_generate_pdf_wizard, self).add_selections(cr, uid, ids, directory, log, context=context)
-
-training_seance_generate_pdf_wizard()
-
-class exam_wizard_helper(osv.osv_memory):
- _name = 'training.exam.wizard.helper'
-
- _columns = {
- 'questionnaire_id' : fields.many2one('training.exam.questionnaire', 'Questionnaire', required=True, select=1),
- 'question_ids' : fields.many2many('training.exam.question', 'training_exam_wizard_helper_rel', 'helper_id', 'question_id', 'Questions', ),
- 'course_id' : fields.many2one('training.course', 'Course', context={'quizz_search': 1}),
- 'kind' : fields.char('Kind', size=32),
- }
-
- def _default_questionnaire_id(self, cr, uid, context=None):
- return context and context.get('active_id', False) or False
-
- def _default_course_id(self, cr, uid, context=None):
- active_id = context and context.get('active_id', False) or False
-
- questionnaire = self.pool.get('training.exam.questionnaire').browse(cr, uid, active_id, context=context)
- if questionnaire.type == 'examen':
- r = questionnaire.main_course_id.id
- else:
- r = len(questionnaire.course_ids) and questionnaire.course_ids[0].course_id.id or None
- return r
-
- _defaults = {
- 'questionnaire_id' : _default_questionnaire_id,
- 'course_id' : _default_course_id,
- }
-
- def cancel_cb(self, cr, uid, ids, context=None):
- return {'type' : 'ir.actions.act_window_close'}
-
- def add_questions_cb(self, cr, uid, ids, context=None):
-
- this = self.browse(cr, uid, ids[0], context=context)
-
- proxy = self.pool.get('training.exam.questionnaire.question')
-
- # get current and next sequence number (to keep question ordering)
- cr.execute(
- """SELECT max(sequence)
- FROM training_exam_questionnaire_question
- WHERE questionnaire_id = %s""",
- (int(this.questionnaire_id.id),)
- )
- current_sequence = cr.fetchone()
- next_sequence = 0
- if current_sequence:
- next_sequence = (current_sequence[0] or 0) + 1
-
- for idx, question in enumerate(this.question_ids):
- proxy.create(cr, uid,
- {
- 'sequence': next_sequence + idx,
- 'question_id' : question.id,
- 'questionnaire_id' : this.questionnaire_id.id,
- }, context=context)
-
- return {'type' : 'ir.actions.act_window_close'}
-
-exam_wizard_helper()
-
class training_exam_questionnaire_attachment(osv.osv):
_name = 'training.exam.questionnaire.attachment'
_description = 'training.exam.questionnaire.attachment'
@@ -2191,8 +1804,7 @@
tpl.participation_id
) AS z ON tpcl.course_id = z.id AND tp.id = z.participation_id
)""")
+
training_exam_contact_results_stat()
-
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'training_exam/training_exam_view.xml'
--- training_exam/training_exam_view.xml 2011-02-24 14:32:11 +0000
+++ training_exam/training_exam_view.xml 2011-03-17 09:09:48 +0000
@@ -2,32 +2,6 @@
<openerp>
<data>
- <record model="ir.ui.view" id="training_exam_question_validate_wizard_form">
- <field name="name">training.exam.question.validate.wizard.form</field>
- <field name="model">training.exam.question.validate.wizard</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Validate Wizard" col="2">
- <separator string="Confirmation Required" colspan="2"/>
- <field name="questionnaire_ids" height="300" colspan="2"/>
- <group colspan="2" col="6">
- <field name="state" invisible="1"/>
- <button type="special" special="cancel" string="Cancel"/>
- <button type="object" name="action_validate_wo_qz" string="Validate (without Quizz)"/>
- <button type="object" name="action_validate_w_qz" string="Validate (with Quizz)"/>
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="training_exam_question_validate_wizard_action">
- <field name="name">Question Validate Wizard</field>
- <field name="res_model">training.exam.question.validate.wizard</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- </record>
-
<record model="ir.ui.view" id="course_type_form_inherited">
<field name="name">training.course_type.form.inherited</field>
<field name="model">training.course_type</field>
@@ -40,30 +14,6 @@
</field>
</record>
- <record model="ir.ui.view" id="exam_question_new_version_form">
- <field name="name">training.exam.question.new.version.wizard.form</field>
- <field name="model">training.exam.question.new.version.wizard</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Create New Revision">
- <label string="Are you sure you want to create a new version?"/>
- <field name="note" nolabel="1" colspan="4"/>
- <group colspan="4" col="2">
- <button type="special" special="cancel" string="Cancel"/>
- <button type="object" name="action_create_new_version" string="Create"/>
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_question_new_version_action">
- <field name="name">Create New Version</field>
- <field name="res_model">training.exam.question.new.version.wizard</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- </record>
-
<act_window id="link_question_to_questionnaire"
name="Questionnaires"
src_model="training.exam.question"
@@ -157,9 +107,9 @@
</notebook>
<group colspan="4" col="9">
<field name="state"/>
- <button type="action" name="%(training_exam.exam_question_new_version_action)d" string="Create New Version" states="validated,deprecated"/>
- <button type="action" name="%(training_exam_question_validate_wizard_action)d" string="Validate" states="draft"/>
- <button type="action" name="%(wizard_question_deprecate_action)d" string="Deprecate" states="validated"/>
+ <button type="action" name="%(training_exam.exam_question_new_version_action)d" icon="terp-document-new" string="Create New Version" states="validated,deprecated"/>
+ <button type="action" name="%(training_exam_question_validate_wizard_action)d" icon="gtk-go-up" string="Validate" states="draft"/>
+ <button type="action" name="%(wizard_question_deprecate_action)d" string="Deprecate" icon="terp-dialog-close" states="validated"/>
</group>
</form>
</field>
@@ -201,6 +151,29 @@
</field>
</record>
+ <record model="ir.ui.view" id="exam_question_search_version">
+ <field name="name">training.exam.question.version.search</field>
+ <field name="model">training.exam.question</field>
+ <field name="type">search</field>
+ <field name="priority">100</field>
+ <field name="arch" type="xml">
+ <search string="Search Exam Question">
+ <filter icon="terp-document-new" string="Draft" domain="[('state','=', 'draft')]"/>
+ <filter icon="gtk-go-up" string="Validate" domain="[('state','=', 'validated')]"/>
+ <filter icon="terp-dialog-close" string="Deprecate" domain="[('state','=', 'deprecated')]"/>
+ <separator orientation="vertical"/>
+ <field name="type"/>
+ <field name="name"/>
+ <field name="question"/>
+ <newline/>
+ <group expand="0" string="Group By..." >
+ <filter string="Type" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'type'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
<act_window id="link_training_exam_question_self_all_versions"
name="Show All Versions"
src_model="training.exam.question"
@@ -228,81 +201,7 @@
<field name="res_model">training.exam.question</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
- <field name="domain">[('version','=',0)]</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_question_all_versions_act">
- <field name="name">All Questions Versions</field>
- <field name="res_model">training.exam.question</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_question_new_act">
- <field name="name">New Question</field>
- <field name="res_model">training.exam.question</field>
- <field name="view_type">form</field>
- <field name="view_mode">form,tree</field>
- <field name="domain">[('version','=',0)]</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_question_without_act">
- <field name="name">Questions Without Course</field>
- <field name="res_model">training.exam.question</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="context">{'course':'cid'}</field>
- </record>
-
- <record model="ir.ui.view" id="exam_questionnaire_wizard_helper_form">
- <field name="name">Add Questions (helper)</field>
- <field name="model">training.exam.wizard.helper</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Add Questions to Questionnaire">
- <field name="questionnaire_id" invisible="1" />
- <field name="course_id" />
- <newline />
- <field name="question_ids" nolabel="1" colspan="4"
- context="{'course_id' : course_id}" domain="[('state','in',['draft','validated'])]" />
- <group colspan="4" col="2">
- <button name="cancel_cb" string="Cancel" special="cancel" type="object" />
- <button name="add_questions_cb" string="Add Questions" type="object" />
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_wizard_helper_act">
- <field name="name">Add Questions</field>
- <field name="res_model">training.exam.wizard.helper</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- </record>
-
- <record model="ir.ui.view" id="exam_questionnaire_new_version_form">
- <field name="name">training.exam.questionnaire.new.version.wizard.form</field>
- <field name="model">training.exam.questionnaire.new.version.wizard</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Create New Revision">
- <label string="Are you sure you want to create a new version?"/>
- <field name="note" colspan="4" nolabel="1"/>
- <group colspan="4" col="2">
- <button type="special" special="cancel" string="Cancel"/>
- <button type="object" name="action_create_new_version" string="Create"/>
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_new_version_action">
- <field name="name">Create New Version</field>
- <field name="res_model">training.exam.questionnaire.new.version.wizard</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
+ <field name="search_view_id" ref="exam_question_search_version"/>
</record>
<record model="ir.ui.view" id="training_exam_questionnaire_course_tree">
@@ -319,7 +218,7 @@
</tree>
</field>
</record>
-
+
<record model="ir.ui.view" id="training_exam_questionnaire_course_from">
<field name="name">training.exam.questionnaire.course.form</field>
<field name="model">training.exam.questionnaire.course</field>
@@ -370,7 +269,7 @@
<field name="course_ids" nolabel="1" colspan="4" attrs="{'readonly': [('state','=','validated')]}"/>
</page>
<page string="Questions">
- <button name="%(exam_questionnaire_wizard_helper_act)d" string="Add Questions" type="action" colspan="4" attrs="{'readonly': [('state','=','validated')]}"/>
+ <button name="%(exam_questionnaire_wizard_helper_act)d" icon="terp-document-new" string="Add Questions" type="action" colspan="4" attrs="{'readonly': [('state','=','validated')]}"/>
<field name="question_ids" colspan="4" nolabel="1" attrs="{'readonly' : [('state', '=', 'validated')]}">
<tree string="Questions">
<field name="sequence"/>
@@ -406,9 +305,9 @@
</notebook>
<group colspan="4" col="8">
<field name="state" />
- <button name="signal_teq_deprecate" string="Deprecate" type="workflow" states="inprogress,validated" confirm="Do you want to deprecate this questionnaire ?" />
- <button name="signal_teq_validate" string="Validate" type="workflow" states="inprogress,draft" confirm="Do you want to validate this questionnaire ?" />
- <button name="%(training_exam.exam_questionnaire_new_version_action)d" string="Create a New Version" type="action" states="validated,deprecated"/>
+ <button name="signal_teq_deprecate" icon="terp-dialog-close" string="Deprecate" type="workflow" states="inprogress,validated" confirm="Do you want to deprecate this questionnaire ?" />
+ <button name="signal_teq_validate" icon="gtk-go-up" string="Validate" type="workflow" states="inprogress,draft" confirm="Do you want to validate this questionnaire ?" />
+ <button name="%(training_exam.exam_questionnaire_new_version_action)d" icon="terp-document-new" string="Create a New Version" type="action" states="validated,deprecated"/>
</group>
</form>
</field>
@@ -441,7 +340,7 @@
name="Questions"
src_model="training.exam.questionnaire"
res_model="training.exam.question"
- domain="[('id','in', [ x[2]['question_id'] for x in question_ids ])]"
+ domain="[('id','in', [ x[2]['question_id'] for x in question_ids ])]"
/>
<act_window id="show_questionnaire_from_course"
@@ -459,17 +358,43 @@
<tree string="Questionnaires">
<field name="reference"/>
<field name="version"/>
- <field name="name" />
- <field name="course_ids" />
- <field name="duration" />
- <field name="kind" />
+ <field name="name"/>
+ <field name="course_ids"/>
+ <field name="duration"/>
+ <field name="kind"/>
<field name="passing_score"/>
- <field name="state" />
+ <field name="state"/>
+ <field name="type"/>
<field name="printable"/>
</tree>
</field>
</record>
+ <record model="ir.ui.view" id="exam_questionnaire_search">
+ <field name="name">training.exam.questionnaire.search</field>
+ <field name="model">training.exam.questionnaire</field>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Search Session">
+ <filter icon="terp-document-new" string="Draft" domain="[('state', '=', 'draft')]"/>
+ <filter icon="gtk-go-up" string="Validate" domain="[('state','=', 'validated')]"/>
+ <filter icon="terp-dialog-close" string="Deprecate" domain="[('state','=', 'deprecated')]"/>
+ <separator orientation="vertical"/>
+ <field name="kind"/>
+ <field name="name"/>
+ <field name="reference"/>
+ <field name="printable"/>
+ <field name="main_course_id"/>
+ <field name="type"/>
+ <newline/>
+ <group expand="0" string="Group By...">
+ <filter string="type" icon="terp-check" domain="[]" context="{'group_by':'type'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
<record model="ir.ui.view" id="exam_questionnaire_tree_version">
<field name="name">training.exam.questionnaire.version.tree</field>
<field name="model">training.exam.questionnaire</field>
@@ -516,30 +441,7 @@
<field name="res_model">training.exam.questionnaire</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
- <field name="domain">[('version','=',0)]</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_all_versions_act">
- <field name="name">All Questionnaires Versions</field>
- <field name="res_model">training.exam.questionnaire</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_current_act">
- <field name="name">Current Questionnaires</field>
- <field name="res_model">training.exam.questionnaire</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,form</field>
- <field name="domain">[('state', '=', 'validated'),('version','=',0)]</field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_new_act">
- <field name="name">New Questionnaire</field>
- <field name="res_model">training.exam.questionnaire</field>
- <field name="view_type">form</field>
- <field name="view_mode">form,tree</field>
- <field name="domain">[('version','=',0)]</field>
+ <field name="search_view_id" ref="exam_questionnaire_search"/>
</record>
<record id="exam_question_answer_form" model="ir.ui.view">
@@ -629,59 +531,6 @@
res_model="training.exam.question"
domain="[('course_ids', '=', [active_id])]" />
- <record model="ir.ui.view" id="question_wizard_form">
- <field name="name">training.exam.question.wizard.form</field>
- <field name="model">training.exam.question.wizard</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Question Wizard" col="4">
- <separator string="Question Wizard" colspan="4"/>
- <field name="course_id" colspan="4"/>
- <group colspan="4">
- <button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
- <button name="find_question_with_course" string="_Apply" icon="gtk-apply" type="object" />
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="question_wizard_act">
- <field name="name">Questions by Course</field>
- <field name="res_model">training.exam.question.wizard</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- </record>
-
- <record model="ir.ui.view" id="exam_questionnaire_wizard_form">
- <field name="name">training.exam.questionnaire.wizard.form</field>
- <field name="model">training.exam.questionnaire.wizard</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <form string="Questionnaire Wizard" col="2">
- <separator string="Questionnaire Information" colspan="2" />
- <field name="name" />
- <field name="course_id" />
- <separator string="Information about the questions" colspan="2"/>
- <field name="kind" />
- <field name="number_of_question" />
- <separator colspan="2" />
- <group colspan="2">
- <button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" type="object"/>
- <button name="action_generate_questionnaire" string="_Apply" icon="gtk-apply" type="object" />
- </group>
- </form>
- </field>
- </record>
-
- <record model="ir.actions.act_window" id="exam_questionnaire_wizard_act">
- <field name="name">Generate Questionnaire</field>
- <field name="res_model">training.exam.questionnaire.wizard</field>
- <field name="view_type">form</field>
- <field name="view_mode">form</field>
- <field name="target">new</field>
- </record>
-
<record model="ir.ui.view" id="offer_form_with_questionnaires">
<field name="name">training.offer.form.with.questionnaires</field>
<field name="model">training.offer</field>
@@ -711,7 +560,7 @@
</field>
<field name="kind" position="after">
<group colspan="2" col="2" attrs="{'invisible': [('kind', '!=', 'exam')]}">
- <field name="course_id" string="Exam"
+ <field name="course_id" string="Exam"
attrs="{'required': [('kind', '=', 'exam')], 'readonly': [('state', '!=', 'draft')]}"
on_change="on_change_exam(session_id, price_list_id, course_id, partner_id)"
link="0" />
@@ -723,7 +572,7 @@
</data>
</field>
</record>
-
+
<record model="ir.ui.view" id="subscription_line_tree_inherited">
<field name="name">training.subscription.line.tree.inherited</field>
<field name="model">training.subscription.line</field>
@@ -763,9 +612,9 @@
</xpath>
<xpath expr="/form/notebook/page[@string='Subscription']/field[@name='subscription_line_ids']/form/field[@name='kind']" position="after">
<group colspan="2" col="2" attrs="{'invisible': [('kind', '!=', 'exam')]}">
- <field name="course_id" string="Exam"
+ <field name="course_id" string="Exam"
attrs="{'required': [('kind', '=', 'exam')]}"
- link="0"
+ link="0"
on_change="on_change_exam(session_id, price_list_id, course_id, parent.partner_id)"/>
</group>
</xpath>
@@ -773,7 +622,7 @@
<attribute name="on_change">on_change_price_list(session_id, price_list_id, course_id)</attribute>
</xpath>
<xpath expr="/form/notebook/page[@string='Subscription']/field[@name='subscription_line_ids']" position="before">
- <button name="action_subscription_line_compute" string="Compute Exam Subscription" type="object" colspan="2" states="draft" />
+ <button name="action_subscription_line_compute" icon="gtk-execute" string="Compute Exam Subscription" type="object" colspan="2" states="draft" />
</xpath>
</data>
</field>
@@ -904,7 +753,7 @@
<field name="succeeded" />
<field name="kind_questionnaire_id" select="2" invisible="1"/>
<field name="certif_printed" groups="base.group_user"/>
- </field>
+ </field>
</field>
</record>
@@ -1042,127 +891,19 @@
<menuitem
id="library_exam_mi"
parent="training.training_library_mi"
- name="Exams" />
+ name="Exams" sequence="2"/>
<!-- Training/ Library/ Exams/ Exams-->
<menuitem
id="library_exam_questionnaire_all_mi"
parent="library_exam_mi"
- action="exam_questionnaire_all_act" />
- <!-- Training/ Library/ Exams/ Questionnaires/ Current Exams-->
- <menuitem
- id="library_exam_current_mi"
- parent="library_exam_questionnaire_all_mi"
- action="exam_questionnaire_current_act" />
-
- <!-- Training/ Library/ Exams/ Questionnaires/ Generate Questionnaire -->
- <menuitem
- id="library_exam_questionnaire_generate_mi"
- parent="library_exam_questionnaire_all_mi"
- action="exam_questionnaire_wizard_act" />
-
- <!-- Training/ Library/ Exams/ Questionnaires/ New Exam-->
- <menuitem
- id="library_exam_new_mi"
- parent="library_exam_questionnaire_all_mi"
- action="exam_questionnaire_new_act" />
-
- <!-- Training / Library / Exams / Questionnaires / All Questionnaires Versions -->
- <menuitem
- id="library_exam_questionnaire_all_versions_mi"
- parent="library_exam_questionnaire_all_mi"
- action="exam_questionnaire_all_versions_act"/>
+ action="exam_questionnaire_all_act" sequence="1"/>
<!-- Training/ Library/ Exams/ Questions -->
<menuitem
id="library_exam_question_mi"
parent="library_exam_mi"
- action="exam_question_all_act"/>
-
- <!-- Training/ Library/ Exams/ Without Couser Question -->
- <menuitem
- id="library_exam_question_mi1"
- parent="library_exam_question_mi"
- action="exam_question_without_act" />
-
- <!-- Training/ Library/ Exams/ Questions By Course -->
- <menuitem
- id="library_exam_question_course_wizard_mi"
- parent="library_exam_question_mi"
- action="question_wizard_act" />
-
- <!-- Training/ Library/ Exams/ New Question -->
- <menuitem
- id="library_exam_question_new_mi"
- parent="library_exam_question_mi"
- action="exam_question_new_act" />
-
- <!-- Training / Library / Exams / Questions / All Questions Versions -->
- <menuitem
- id="library_exam_question_all_versions_mi"
- parent="library_exam_question_mi"
- action="exam_question_all_versions_act"/>
-
- </data>
-
- <data>
- <record model="ir.ui.view" id="subscription_mass_line_form">
- <field name="name">training.subscription.mass.line.form</field>
- <field name="model">training.subscription.mass.line</field>
- <field name="inherit_id" ref="training.subscription_mass_line_form" />
- <field name="type">form</field>
- <field name="arch" type="xml">
- <data>
- <field name="session_id" position="attributes">
- <attribute name="on_change">on_change_session(session_id)</attribute>
- </field>
-
- <field name="kind" position="attributes">
- <attribute name="invisible">0</attribute>
- </field>
- <field name="session_id" position="after">
- <field name="date_session" />
- <field name="exam_session_id" attrs="{'readonly' : [('kind', '=', 'exam')]}" />
- <field name="course_id"
- attrs="{'readonly':[('kind', '!=', 'exam')], 'required':[('kind', '=', 'exam')]}"
- domain="[('has_questionnaire', '=', True)]" />
- </field>
- </data>
- </field>
- </record>
-
- <record model="ir.ui.view" id="subscription_mass_line_tree">
- <field name="name">training.subscription.mass.line.tree</field>
- <field name="model">training.subscription.mass.line</field>
- <field name="inherit_id" ref="training.subscription_mass_line_tree" />
- <field name="type">tree</field>
- <field name="arch" type="xml">
- <data>
- <field name="session_id" position="after">
- <field name="date_session" />
- <field name="course_id" />
- <field name="exam_session_id" />
- </field>
- <field name="kind" position="attributes">
- <attribute name="invisible">0</attribute>
- </field>
- </data>
- </field>
- </record>
- </data>
-
- <data>
- <record model="ir.ui.view" id="exam_seance_generate_zip_wizard_form">
- <field name="name">training.exam.seance.generate.zip.wizard.form</field>
- <field name="model">training.seance.generate.zip.wizard</field>
- <field name="inherit_id" ref="training.seance_generate_zip_wizard_form" />
- <field name="type">form</field>
- <field name="arch" type="xml">
- <field name="remuneration_form_report" position="after">
- <separator string="Exam Reports" colspan="2" />
- <field name="exams_report" />
- </field>
- </field>
- </record>
+ action="exam_question_all_act" sequence="2"/>
+
</data>
<data>
=== removed file 'training_exam/training_exam_wizard.xml'
--- training_exam/training_exam_wizard.xml 2009-07-31 05:00:27 +0000
+++ training_exam/training_exam_wizard.xml 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<openerp>
- <data>
- <wizard
- id="wizard_training_exam_question_assign_course"
- keyword="client_action_multi"
- model="training.exam.question"
- name="training.exam.question.assign.course"
- multi="True"
- string="Assign Course"/>
- </data>
-</openerp>
=== modified file 'training_exam/wizard/__init__.py'
--- training_exam/wizard/__init__.py 2011-02-25 12:33:02 +0000
+++ training_exam/wizard/__init__.py 2011-03-17 09:09:48 +0000
@@ -22,11 +22,17 @@
#
############################################################################################
-import wizard_question_assign_course
-import wizard_print_raw_questionnaire
-import wizard_validate_question
-import wizard_deprecate_question
-import wizard_questionnaire_create_new_version
-import wizard_question_create_new_version
+import training_exam_question_assign_course
+import training_exam_print_questionnaire_raw
+import training_exam_validate_question
+import training_exam_depricate_question
+import training_exam_questionnaire_create_new_version
+import training_exam_question_create_new_version
+import training_exam_add_question
+import training_seance_generate
+import training_subscription_mass_line
+import training_exam_question
+import training_exam_questionnaire
+import training_exam_question_validate
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_exam_add_question.py'
--- training_exam/wizard/training_exam_add_question.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_add_question.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,96 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+
+class exam_wizard_helper(osv.osv_memory):
+ _name = 'training.exam.wizard.helper'
+
+ _columns = {
+ 'questionnaire_id' : fields.many2one('training.exam.questionnaire', 'Questionnaire', required=True, select=1),
+ 'question_ids' : fields.many2many('training.exam.question', 'training_exam_wizard_helper_rel', 'helper_id', 'question_id', 'Questions', ),
+ 'course_id' : fields.many2one('training.course', 'Course', context={'quizz_search': 1}),
+ 'kind' : fields.char('Kind', size=32),
+ }
+
+ def _default_questionnaire_id(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ return context and context.get('active_id', False) or False
+
+ def _default_course_id(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ active_id = context and context.get('active_id', False) or False
+
+ questionnaire = self.pool.get('training.exam.questionnaire').browse(cr, uid, active_id, context=context)
+ if questionnaire.type == 'examen':
+ result = questionnaire.main_course_id.id
+ else:
+ result = len(questionnaire.course_ids) and questionnaire.course_ids[0].course_id.id or None
+ return result
+
+ _defaults = {
+ 'questionnaire_id' : _default_questionnaire_id,
+ 'course_id' : _default_course_id,
+ }
+
+ def cancel_cb(self, cr, uid, ids, context=None):
+ return {'type' : 'ir.actions.act_window_close'}
+
+ def add_questions_cb(self, cr, uid, ids, context=None):
+ if not ids:
+ return False
+ if context is None:
+ context = {}
+ this = self.browse(cr, uid, ids[0], context=context)
+
+ proxy = self.pool.get('training.exam.questionnaire.question')
+
+ # get current and next sequence number (to keep question ordering)
+ cr.execute(
+ """SELECT max(sequence)
+ FROM training_exam_questionnaire_question
+ WHERE questionnaire_id = %s""",
+ (int(this.questionnaire_id.id),)
+ )
+ current_sequence = cr.fetchone()
+ next_sequence = 0
+ if current_sequence:
+ next_sequence = (current_sequence[0] or 0) + 1
+
+ for idx, question in enumerate(this.question_ids):
+ proxy.create(cr, uid,
+ {
+ 'sequence': next_sequence + idx,
+ 'question_id' : question.id,
+ 'questionnaire_id' : this.questionnaire_id.id,
+ }, context=context)
+
+ return {'type' : 'ir.actions.act_window_close'}
+
+exam_wizard_helper()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_exam_add_question_view.xml'
--- training_exam/wizard/training_exam_add_question_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_add_question_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,33 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="exam_questionnaire_wizard_helper_form">
+ <field name="name">Add Questions (helper)</field>
+ <field name="model">training.exam.wizard.helper</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Add Questions to Questionnaire">
+ <field name="questionnaire_id" invisible="1"/>
+ <field name="course_id"/>
+ <newline />
+ <separator colspan="4" string="Questions"/>
+ <field name="question_ids" nolabel="1" colspan="4"
+ context="{'course_id' : course_id}" domain="[('state','in',['draft','validated'])]"/>
+ <group colspan="4" col="2">
+ <button name="cancel_cb" string="Cancel" special="cancel" type="object" icon="gtk-cancel"/>
+ <button name="add_questions_cb" string="Add Questions" type="object" icon="terp-document-new"/>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="exam_questionnaire_wizard_helper_act">
+ <field name="name">Add Questions</field>
+ <field name="res_model">training.exam.wizard.helper</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ </data>
+</openerp>
=== renamed file 'training_exam/wizard/wizard_deprecate_question.py' => 'training_exam/wizard/training_exam_depricate_question.py'
--- training_exam/wizard/wizard_deprecate_question.py 2011-02-17 16:03:44 +0000
+++ training_exam/wizard/training_exam_depricate_question.py 2011-03-17 09:09:48 +0000
@@ -2,7 +2,8 @@
# Copyright 2010 Thamini S.Ã .R.L This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-from osv import osv, fields
+from osv import osv
+from osv import fields
class training_exam_question_group_deprecate(osv.osv_memory):
_name = 'training.exam.question.group.deprecate.wizard'
@@ -12,10 +13,14 @@
}
def button_deprecate(self, cr, uid, ids, context=None):
+ if not ids:
+ return {}
+ if context is None:
+ context = {}
+ question_pool = self.pool.get('training.exam.question')
if context and 'active_ids' in context:
wizard = self.browse(cr, uid, ids[0], context=context)
question_ids = context.get('active_ids')
- question_pool = self.pool.get('training.exam.question')
validated_question_ids = question_pool.search(cr, uid, [('state','in',['validated','draft']),('id','in',question_ids)], context=context)
if wizard.note:
@@ -23,10 +28,8 @@
context['_deprecated_note'] = wizard.note
question_pool.action_deprecate(cr, uid, validated_question_ids, context=context)
- return {
- 'type': 'ir.actions.act_window.close',
- }
- return False
+ return {'type': 'ir.actions.act_window.close'}
training_exam_question_group_deprecate()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
=== renamed file 'training_exam/wizard/wizard_deprecate_question_view.xml' => 'training_exam/wizard/training_exam_depricate_question_view.xml'
=== renamed file 'training_exam/wizard/wizard_print_raw_questionnaire.py' => 'training_exam/wizard/training_exam_print_questionnaire_raw.py'
--- training_exam/wizard/wizard_print_raw_questionnaire.py 2011-02-16 17:40:10 +0000
+++ training_exam/wizard/training_exam_print_questionnaire_raw.py 2011-03-17 09:09:48 +0000
@@ -33,6 +33,8 @@
}
def _get_default_lang(self, cr, uid, context=None):
+ if context is None:
+ context = {}
user_obj = self.pool.get('res.users')
lang_obj = self.pool.get('res.lang')
@@ -49,8 +51,11 @@
}
def button_create_report(self, cr, uid, ids, context=None):
+ if not ids:
+ return {}
+ if context is None:
+ context = {}
wizard = self.browse(cr, uid, ids[0], context=context)
-
if wizard.show_solution:
report_name = 'training.exam.questionnaire.report'
else:
@@ -63,3 +68,4 @@
wizard_print_raw_questionnaire()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
=== renamed file 'training_exam/wizard/wizard_print_raw_questionnaire_view.xml' => 'training_exam/wizard/training_exam_print_questionnaire_raw_view.xml'
=== added file 'training_exam/wizard/training_exam_question.py'
--- training_exam/wizard/training_exam_question.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,60 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+
+class training_question_wizard(osv.osv_memory):
+ _name = 'training.exam.question.wizard'
+ _description = 'Question Wizard'
+
+ _columns = {
+ 'course_id' : fields.many2one('training.course', 'Course', required=True, domain="[('state_course', '=', 'validated')]"),
+ }
+
+ def action_cancel(self, cr, uid, ids, context=None):
+ return {'type':'ir.actions.act_window_close'}
+
+ def find_question_with_course(self, cr, uid, ids, context=None):
+ if not ids:
+ return {}
+ if context is None:
+ context = {}
+ this = self.browse(cr, uid, ids, context=context)[0]
+ context2 = context.copy()
+ context2.update({'course_id':this.course_id.id})
+
+ return {
+ 'view_type': 'form',
+ "view_mode": 'form',
+ 'res_model': 'training.exam.question',
+ 'view_id':self.pool.get('ir.ui.view').search(cr,uid,[('name','=','training.exam.question.tree')]),
+ 'type': 'ir.actions.act_window',
+ 'target':'current',
+ 'context': context2,
+ }
+
+training_question_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== renamed file 'training_exam/wizard/wizard_question_assign_course.py' => 'training_exam/wizard/training_exam_question_assign_course.py'
--- training_exam/wizard/wizard_question_assign_course.py 2011-02-25 12:33:02 +0000
+++ training_exam/wizard/training_exam_question_assign_course.py 2011-03-17 09:09:48 +0000
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
############################################################################################
#
-# OpenERP, Open Source Management Solution
+# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
@@ -22,59 +22,26 @@
#
############################################################################################
-import wizard
-import netsvc
-import ir
-import pooler
-
-confirm_form = """<?xml version="1.0"?>
-<form string="Assign to a new course">
- <field name="course_id" />
-</form>
-"""
-
-confirm_fields = {
- 'course_id' : {
- 'type' : 'many2one',
- 'relation' : 'training.course',
- 'domain' : "[('state_course', '=', 'validated')]",
- 'string' : 'Course',
- 'required' : True,
- }
-}
-
-def _confirm(self, cr, uid, data, context):
-
- proxy = pooler.get_pool(cr.dbname).get('training.exam.question')
- for question in proxy.browse(cr, uid, data['ids'], context=context):
- # Assign the course to the question
- course_ids = set([data['form']['course_id']] + [course.id for course in question.course_ids])
-
- question.write({'course_ids' : [(6, 0, list(course_ids))]})
-
- return {}
-
-class training_exam_question_assign_course(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'}
- },
- }
-
-training_exam_question_assign_course("training.exam.question.assign.course")
+from osv import osv
+from osv import fields
+
+class training_exam_question_assign_course(osv.osv_memory):
+ _name = 'training.exam.question.assign.course'
+ _columns = {
+ 'course_id': fields.many2one('training.course', 'Course', domain="[('state_course','=','validated')]", required=True),
+ }
+
+ def action_confirm(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ proxy = self.pool.get('training.exam.question')
+ for assign_course in self.browse(cr, uid, ids, context):
+ for question in proxy.browse(cr, uid, context.get('active_ids',[]), context=context):
+ course_ids = set([assign_course.course_id.id] + [course.id for course in question.course_ids])
+ question.write({'course_ids' : [(6, 0, list(course_ids))]})
+ return {'type': 'ir.actions.act_window.close'}
+
+
+training_exam_question_assign_course()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
=== added file 'training_exam/wizard/training_exam_question_assign_course_view.xml'
--- training_exam/wizard/training_exam_question_assign_course_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question_assign_course_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,35 @@
+<openerp>
+<data>
+
+ <record model="ir.ui.view" id="wizard_training_exam_question_assign_course_form_view">
+ <field name="name">training.exam.question.assign.course.form</field>
+ <field name="model">training.exam.question.assign.course</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Assign course">
+ <field name="course_id"/>
+ <newline/>
+ <separator colspan="4"/>
+ <group colspan="2" col="2">
+ <button type="special" special="cancel" string="Cancel" colspan="1" icon="gtk-cancel"/>
+ <button type="object" name="action_confirm" string="Confirm" colspan="1" icon="gtk-apply"/>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="wizard_training_exam_question_assign_course_action">
+ <field name="name">Assign Course</field>
+ <field name="res_model">training.exam.question.assign.course</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ <act_window id="action_act_view_training_exam_question_assign_course"
+ key2="client_action_multi" name="Assign Course"
+ res_model="training.exam.question.assign.course" src_model="training.exam.question"
+ view_mode="form" target="new" view_type="form" />
+
+</data>
+</openerp>
=== renamed file 'training_exam/wizard/wizard_question_create_new_version.py' => 'training_exam/wizard/training_exam_question_create_new_version.py'
--- training_exam/wizard/wizard_question_create_new_version.py 2011-02-17 15:01:44 +0000
+++ training_exam/wizard/training_exam_question_create_new_version.py 2011-03-17 09:09:48 +0000
@@ -22,7 +22,6 @@
##############################################################################
import time
-import netsvc
from osv import osv
from osv import fields
from tools.translate import _
@@ -36,6 +35,8 @@
}
def _create_new_revision(self, cr, uid, id, context=None, note=None):
+ if context is None:
+ context = {}
def _get_last_revision(reference):
cr.execute("SELECT MAX(version) FROM training_exam_question WHERE reference = %s", (reference,))
r = cr.fetchone()
@@ -92,6 +93,8 @@
def action_create_new_version(self, cr, uid, ids, context=None):
if not ids:
return {}
+ if context is None:
+ context = {}
wizard = self.browse(cr, uid, ids[0], context=context)
active_id = context.get('active_id', None)
new_id = self._create_new_revision(cr, uid, active_id, context=context, note=wizard.note)
@@ -104,3 +107,5 @@
}
training_exam_question_new_version_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_exam_question_create_new_version_view.xml'
--- training_exam/wizard/training_exam_question_create_new_version_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question_create_new_version_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,30 @@
+<openerp>
+ <data>
+
+
+ <record model="ir.ui.view" id="exam_question_new_version_form">
+ <field name="name">training.exam.question.new.version.wizard.form</field>
+ <field name="model">training.exam.question.new.version.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Create New Revision">
+ <label string="Are you sure you want to create a new version?"/>
+ <field name="note" nolabel="1" colspan="4"/>
+ <group colspan="4" col="2">
+ <button type="special" icon="gtk-cancel" special="cancel" string="Cancel"/>
+ <button type="object" icon="terp-document-new" name="action_create_new_version" string="Create"/>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="exam_question_new_version_action">
+ <field name="name">Create New Version</field>
+ <field name="res_model">training.exam.question.new.version.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'training_exam/wizard/training_exam_question_validate.py'
--- training_exam/wizard/training_exam_question_validate.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question_validate.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,97 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+import netsvc
+
+class training_exam_question_validate_wizard(osv.osv_memory):
+ _name = 'training.exam.question.validate.wizard'
+
+ _columns = {
+ 'questionnaire_ids': fields.many2many('training.exam.questionnaire', 'training_exam_questionnaire_question_rel', 't1', 't2', 'Questionnaires'),
+ 'state': fields.selection([('init', 'Init'),('validate_w_quizz', 'Validate With Quizz'),('validate_wo_quizz', 'Validate Without Quizz')], 'State'),
+ }
+
+ def _has_questionnaire_validated(self, cr, uid, question_id, context=None):
+ if context is None:
+ context = {}
+ qz_pool = self.pool.get('training.exam.questionnaire')
+ if not question_id:
+ return []
+
+ cr.execute("""
+ SELECT teqq.questionnaire_id
+ FROM training_exam_questionnaire_question teqq
+ LEFT JOIN training_exam_question teqn ON (teqq.question_id = teqn.id)
+ WHERE teqq.questionnaire_id IN (
+ SELECT distinct(questionnaire_id)
+ FROM training_exam_questionnaire_question teqq
+ WHERE teqq.question_id = %(qid)s)
+ GROUP BY teqq.questionnaire_id
+ HAVING count(teqn.id) - 1 = sum(CASE WHEN (teqn.state = 'validated' AND teqn.id != %(qid)s) THEN 1 ELSE 0 END)
+ """, {'qid': question_id})
+
+ qz_ids = [ x[0] for x in cr.fetchall() ]
+ return qz_ids
+
+ def _get_default_state(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ ids = self._has_questionnaire_validated(cr, uid, context.get('active_id'), context=context)
+ if not ids:
+ return 'validate_wo_quizz'
+ return 'validate_w_quizz'
+
+ def _get_default_questionnaire(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ return self._has_questionnaire_validated(cr, uid, context.get('active_id'), context=context)
+
+ def action_validate_wo_qz(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ if context.get('active_id'):
+ self.pool.get('training.exam.question').write(cr, uid, [context.get('active_id')], {'state': 'validated'}, context=context)
+ return {}
+
+ def action_validate_w_qz(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ wkf = netsvc.LocalService('workflow')
+ if context.get('active_id'):
+ self.pool.get('training.exam.question').write(cr, uid, [qid], {'state': 'validated'}, context=context)
+ for qwiz in self.browse(cr, uid, ids, context=context):
+ for qz in qwiz.questionnaire_ids:
+ wkf.trg_validate(uid, 'training.exam.questionnaire', qz.id, 'signal_teq_validate', cr)
+ return {}
+
+ _defaults = {
+ 'state': _get_default_state,
+ 'questionnaire_ids': _get_default_questionnaire,
+ }
+
+training_exam_question_validate_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_exam_question_validate_view.xml'
--- training_exam/wizard/training_exam_question_validate_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question_validate_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,31 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="training_exam_question_validate_wizard_form">
+ <field name="name">training.exam.question.validate.wizard.form</field>
+ <field name="model">training.exam.question.validate.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Validate Wizard" col="2">
+ <separator string="Confirmation Required" colspan="2"/>
+ <field name="questionnaire_ids" height="300" colspan="2"/>
+ <group colspan="2" col="6">
+ <field name="state" invisible="1"/>
+ <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+ <button type="object" icon="gtk-go-up" name="action_validate_wo_qz" string="Validate (without Quizz)"/>
+ <button type="object" icon="gtk-ok" name="action_validate_w_qz" string="Validate (with Quizz)"/>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="training_exam_question_validate_wizard_action">
+ <field name="name">Question Validate Wizard</field>
+ <field name="res_model">training.exam.question.validate.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'training_exam/wizard/training_exam_question_view.xml'
--- training_exam/wizard/training_exam_question_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_question_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,35 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="question_wizard_form">
+ <field name="name">training.exam.question.wizard.form</field>
+ <field name="model">training.exam.question.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Question Wizard" col="4">
+ <separator string="Question Wizard" colspan="4"/>
+ <field name="course_id" colspan="4"/>
+ <group colspan="4">
+ <button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
+ <button name="find_question_with_course" string="_Apply" icon="gtk-apply" type="object" />
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="question_wizard_act">
+ <field name="name">Questions by Course</field>
+ <field name="res_model">training.exam.question.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ <!-- Training/ Library/ Exams/ Questions By Course -->
+ <menuitem
+ id="library_exam_question_course_wizard_mi"
+ parent="library_exam_mi"
+ action="question_wizard_act" sequence="4"/>
+
+ </data>
+</openerp>
=== added file 'training_exam/wizard/training_exam_questionnaire.py'
--- training_exam/wizard/training_exam_questionnaire.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_questionnaire.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,111 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+import random
+
+class exam_questionnaire_wizard(osv.osv_memory):
+ _name = 'training.exam.questionnaire.wizard'
+ _description = 'Questionnaire Wizard'
+
+ _columns = {
+ 'name' : fields.char('Name', size=64, required=True),
+ 'course_id' : fields.many2one('training.course', 'Course', required=True, domain="[('state_course', '=', 'validated')]"),
+ 'number_of_question' : fields.integer('Number of Questions'),
+ 'kind' : fields.selection(
+ [
+ ('automatic', 'Automatic'),
+ ('manual', 'At Least one open-ended question')
+ ],
+ 'Type'),
+ }
+
+ _defaults = {
+ 'kind' : lambda *a: 'automatic',
+ 'number_of_question' : lambda *a: 20,
+ }
+
+ def action_cancel(self, cr, uid, ids, context=None):
+ return {'type':'ir.actions.act_window_close'}
+
+ def action_generate_questionnaire(self, cr, uid, ids, context=None):
+ if not ids:
+ return {}
+ if context is None:
+ context = {}
+ question_proxy = self.pool.get('training.exam.question')
+ this = self.browse(cr, uid, ids, context=context)[0]
+ all_question_ids = question_proxy.search(cr, uid, [], context=context)
+ mandatory_question_ids = []
+ question_ids = []
+ for question in question_proxy.browse(cr, uid, all_question_ids, context=context):
+ if this.course_id in question.course_ids:
+ if question.is_mandatory:
+ mandatory_question_ids.append(question.id)
+ else:
+ question_ids.append(question.id)
+
+ mqids = []
+ qids = []
+
+ number_of_mandatory_questions = random.randint(0, 3)
+ number_of_questions = min(max(20, this.number_of_question) - number_of_mandatory_questions,len(question_ids))
+
+ while number_of_mandatory_questions:
+ try:
+ idx = random.randint(0, len(mandatory_question_ids))
+ mqids.append(mandatory_question_ids[idx])
+ del mandatory_question_ids[idx]
+ except:
+ pass
+ number_of_mandatory_questions -= 1
+
+ while number_of_questions:
+ try:
+ idx = random.randint(0, len(question_ids))
+ qids.append(question_ids[idx])
+ del question_ids[idx]
+ number_of_questions -= 1
+ except:
+ pass
+
+ return {
+ 'view_type': 'form',
+ "view_mode": 'form',
+ 'res_model': 'training.exam.questionnaire',
+ 'view_id':self.pool.get('ir.ui.view').search(cr,uid,[('name','=','training.exam.questionnaire.form')]),
+ 'type': 'ir.actions.act_window',
+ 'target':'current',
+ 'context' : {
+ 'default_name' : this.name,
+ 'default_course_id' : this.course_id.id,
+ 'default_question_ids' : mqids + qids,
+ 'default_kind' : this.kind,
+ }
+ }
+
+exam_questionnaire_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== renamed file 'training_exam/wizard/wizard_questionnaire_create_new_version.py' => 'training_exam/wizard/training_exam_questionnaire_create_new_version.py'
--- training_exam/wizard/wizard_questionnaire_create_new_version.py 2011-01-09 12:49:14 +0000
+++ training_exam/wizard/training_exam_questionnaire_create_new_version.py 2011-03-17 09:09:48 +0000
@@ -34,6 +34,8 @@
}
def _create_new_revision(self, cr, uid, id, context=None, note=None):
+ if context is None:
+ context = {}
def _get_last_revision(reference):
cr.execute("SELECT MAX(version) FROM training_exam_questionnaire WHERE reference = %s", (reference,))
r = cr.fetchone()
@@ -73,6 +75,8 @@
def action_create_new_version(self, cr, uid, ids, context=None):
if not ids:
return {}
+ if context is None:
+ context = {}
wizard = self.browse(cr, uid, ids[0], context=context)
active_id = context.get('active_id', None)
new_id = self._create_new_revision(cr, uid, active_id, context=context, note=wizard.note)
@@ -85,3 +89,5 @@
}
training_exam_questionnaire_new_version_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_exam_questionnaire_create_new_version_view.xml'
--- training_exam/wizard/training_exam_questionnaire_create_new_version_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_questionnaire_create_new_version_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,29 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="exam_questionnaire_new_version_form">
+ <field name="name">training.exam.questionnaire.new.version.wizard.form</field>
+ <field name="model">training.exam.questionnaire.new.version.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Create New Revision">
+ <label string="Are you sure you want to create a new version?"/>
+ <field name="note" colspan="4" nolabel="1"/>
+ <group colspan="4" col="2">
+ <button type="special" special="cancel" string="Cancel" icon="gtk-cancel"/>
+ <button type="object" name="action_create_new_version" string="Create" icon="terp-document-new"/>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="exam_questionnaire_new_version_action">
+ <field name="name">Create New Version</field>
+ <field name="res_model">training.exam.questionnaire.new.version.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'training_exam/wizard/training_exam_questionnaire_view.xml'
--- training_exam/wizard/training_exam_questionnaire_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_exam_questionnaire_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,40 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="exam_questionnaire_wizard_form">
+ <field name="name">training.exam.questionnaire.wizard.form</field>
+ <field name="model">training.exam.questionnaire.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Questionnaire Wizard" col="2">
+ <separator string="Questionnaire Information" colspan="2" />
+ <field name="name" />
+ <field name="course_id" />
+ <separator string="Information about the questions" colspan="2"/>
+ <field name="kind" />
+ <field name="number_of_question" />
+ <separator colspan="2" />
+ <group colspan="2">
+ <button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" type="object"/>
+ <button name="action_generate_questionnaire" string="_Apply" icon="gtk-apply" type="object" />
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="exam_questionnaire_wizard_act">
+ <field name="name">Generate Questionnaire</field>
+ <field name="res_model">training.exam.questionnaire.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ <!-- Training/ Library/ Exams/ Questionnaires/ Generate Questionnaire -->
+ <menuitem
+ id="library_exam_questionnaire_generate_mi"
+ parent="library_exam_mi"
+ action="exam_questionnaire_wizard_act" sequence="3"/>
+
+ </data>
+</openerp>
=== renamed file 'training_exam/wizard/wizard_validate_question.py' => 'training_exam/wizard/training_exam_validate_question.py'
--- training_exam/wizard/wizard_validate_question.py 2010-07-21 14:16:37 +0000
+++ training_exam/wizard/training_exam_validate_question.py 2011-03-17 09:09:48 +0000
@@ -29,16 +29,15 @@
}
def button_validate(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ question_pool = self.pool.get('training.exam.question')
if context and 'active_ids' in context:
question_ids = context.get('active_ids')
- question_pool = self.pool.get('training.exam.question')
draft_question_ids = question_pool.search(cr, uid, [('state','=','draft'),('id','in',question_ids)], context=context)
-
question_pool.action_validate(cr, uid, draft_question_ids, context=context)
- return {
- 'type': 'ir.actions.act_window.close',
- }
- return False
+ return {'type': 'ir.actions.act_window.close'}
training_exam_question_group_validate()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== renamed file 'training_exam/wizard/wizard_validate_question_view.xml' => 'training_exam/wizard/training_exam_validate_question_view.xml'
=== added file 'training_exam/wizard/training_seance_generate.py'
--- training_exam/wizard/training_seance_generate.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_seance_generate.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,84 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+import netsvc
+import time
+import os
+
+class training_seance_generate_pdf_wizard(osv.osv_memory):
+ _inherit = 'training.seance.generate.zip.wizard'
+
+ _columns = {
+ 'exams_report' : fields.boolean('Exams', help="If you select this option, you will print the exams. The filename format is Exam_DATE_PARTICIPATIONID.pdf"),
+ }
+
+ _defaults = {
+ 'exams_report' : lambda *a: False,
+ }
+
+ def _get_report(self, cr, uid, oid, reportname, context=None, data=None):
+ if data is None:
+ data = {}
+ srv = netsvc.LocalService(reportname)
+ pdf, _r = srv.create(cr, uid, [oid], data, context=context)
+ return pdf
+
+ def add_selections(self, cr, uid, ids, directory, log, context=None):
+ if context is None:
+ context = {}
+ active_id = context and context.get('active_id')
+ seance = self.pool.get('training.seance').browse(cr, uid, active_id, context=context)
+ ts = time.strptime(seance.date, '%Y-%m-%d %H:%M:%S')
+ date = time.strftime('%Y%m%d', ts)
+
+ exam_directory = os.path.join(directory, 'Exams')
+ os.mkdir(exam_directory)
+
+ res = []
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.exams_report:
+ for i, part in enumerate(seance.participant_ids):
+ if part.exam_id.forced_noquestionnaire:
+ log.write('ignored participation %d because related exam is marked as: forced no questionnaire\n' % (part.id))
+ continue
+ try:
+ res = self._get_report(cr, uid, part.id, 'report.training.participation.report',
+ context=context, data={'model': 'training.participation', 'id': part.id})
+ except osv.except_osv, e:
+ log.errors += (u'Participation ID: %d got %s\n' % (part.id, e.value))
+ continue
+ #raise e
+
+ filename = os.path.join(exam_directory, 'Exam_%03d_%s_%s_%s_%06d.pdf' % (i, part.contact_lastname, part.contact_firstname, date, part.id))
+ fp = file(filename, 'w')
+ fp.write(res)
+ fp.close()
+
+ super(training_seance_generate_pdf_wizard, self).add_selections(cr, uid, ids, directory, log, context=context)
+
+training_seance_generate_pdf_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_seance_generate_view.xml'
--- training_exam/wizard/training_seance_generate_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_seance_generate_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,18 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="exam_seance_generate_zip_wizard_form">
+ <field name="name">training.exam.seance.generate.zip.wizard.form</field>
+ <field name="model">training.seance.generate.zip.wizard</field>
+ <field name="inherit_id" ref="training.seance_generate_zip_wizard_form" />
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <field name="remuneration_form_report" position="after">
+ <separator string="Exam Reports" colspan="2" />
+ <field name="exams_report" />
+ </field>
+ </field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'training_exam/wizard/training_subscription_mass_line.py'
--- training_exam/wizard/training_subscription_mass_line.py 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_subscription_mass_line.py 2011-03-17 09:09:48 +0000
@@ -0,0 +1,64 @@
+# -*- encoding: utf-8 -*-
+############################################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# Copyright (C) 2008-2009 AJM Technologies S.A. (<http://www.ajm.lu). All Rights Reserved
+# Copyright (C) 2010-2011 Thamini S.Ã .R.L (<http://www.thamini.com>). All Rights Reserved
+# $Id$
+#
+# 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.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+############################################################################################
+
+from osv import osv
+from osv import fields
+
+class mass_subscription_line(osv.osv_memory):
+ _inherit = 'training.subscription.mass.line'
+
+ _columns = {
+ 'date_session' : fields.related('session_id', 'date', type='datetime', string='Date', readonly=True),
+ 'exam_session_id' : fields.many2one('training.session', 'Exam Session'),
+ 'course_id' : fields.many2one('training.course', 'Exam',
+ domain="[('state_course', '=', 'validated')]"),
+ }
+
+ def on_change_session(self, cr, uid, ids, session_id, context=None):
+ if not session_id:
+ return False
+ if context is None:
+ context = {}
+ session = self.pool.get('training.session').browse(cr, uid, session_id, context)
+ dates = [seance.date for seance in session.seance_ids]
+
+ return {
+ 'value' : {
+ 'kind' : session.kind,
+ 'date_session' : session.date,
+ 'exam_session_id': False,
+ 'course_id': False,
+ },
+ 'domain' : {
+ 'exam_session_id' :
+ [('state', 'in', ('opened_confirmed', 'opened', 'closed_confirmed')),
+ ('kind', '=', 'exam'),
+ ('date', '>', len(dates) and max(dates) or session.date),
+ ('id', '!=', session.id)],
+ },
+ }
+
+mass_subscription_line()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'training_exam/wizard/training_subscription_mass_line_view.xml'
--- training_exam/wizard/training_subscription_mass_line_view.xml 1970-01-01 00:00:00 +0000
+++ training_exam/wizard/training_subscription_mass_line_view.xml 2011-03-17 09:09:48 +0000
@@ -0,0 +1,49 @@
+<openerp>
+ <data>
+
+ <record model="ir.ui.view" id="subscription_mass_line_form">
+ <field name="name">training.subscription.mass.line.form</field>
+ <field name="model">training.subscription.mass.line</field>
+ <field name="inherit_id" ref="training.subscription_mass_line_form" />
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <data>
+ <field name="session_id" position="attributes">
+ <attribute name="on_change">on_change_session(session_id)</attribute>
+ </field>
+
+ <field name="kind" position="attributes">
+ <attribute name="invisible">0</attribute>
+ </field>
+ <field name="session_id" position="after">
+ <field name="date_session" />
+ <field name="exam_session_id" attrs="{'readonly' : [('kind', '=', 'exam')]}" />
+ <field name="course_id"
+ attrs="{'readonly':[('kind', '!=', 'exam')], 'required':[('kind', '=', 'exam')]}"
+ domain="[('has_questionnaire', '=', True)]" />
+ </field>
+ </data>
+ </field>
+ </record>
+
+ <record model="ir.ui.view" id="subscription_mass_line_tree">
+ <field name="name">training.subscription.mass.line.tree</field>
+ <field name="model">training.subscription.mass.line</field>
+ <field name="inherit_id" ref="training.subscription_mass_line_tree" />
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <data>
+ <field name="session_id" position="after">
+ <field name="date_session" />
+ <field name="course_id" />
+ <field name="exam_session_id" />
+ </field>
+ <field name="kind" position="attributes">
+ <attribute name="invisible">0</attribute>
+ </field>
+ </data>
+ </field>
+ </record>
+
+ </data>
+</openerp>
Follow ups