[IMP]:survey,crm_hr,hr_evaluation.(Ref-YSA,APA)
[odoo/odoo.git] / addons / survey / survey.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 from osv import fields, osv
24 import datetime
25 from time import strftime
26 import datetime
27 import copy
28 from tools.translate import _
29 from lxml import etree
30 from tools import to_xml
31 import tools
32 from mx.DateTime import *
33 import netsvc
34 import os
35
36 class survey_type(osv.osv):
37     _name = 'survey.type'
38     _description = 'Survey Type'
39     _columns = {
40         'name' : fields.char("Name", size=128, required=1),
41         'code' : fields.char("Code", size=64),
42     }
43 survey_type()
44
45 class survey(osv.osv):
46     _name = 'survey'
47     _description = 'Survey'
48     _rec_name = 'title'
49
50     def default_get(self, cr, uid, fields, context={}):
51         data = super(survey, self).default_get(cr, uid, fields, context)
52         return data
53
54     _columns = {
55         'title' : fields.char('Survey Title', size=128, required=1),
56         'page_ids' : fields.one2many('survey.page', 'survey_id', 'Page'),
57         'date_open' : fields.datetime('Survey Open Date', readonly=1),
58         'date_close' : fields.datetime('Survey Close Date', readonly=1),
59         'max_response_limit' : fields.integer('Maximum Response Limit'),
60         'response_user' : fields.integer('Maximum Response per User',
61                      help="Set to one if  you require only one response per user"),
62         'state' : fields.selection([('draft', 'Draft'), ('open', 'Open'), ('close', 'Closed'), ('cancel', 'Cancelled')], 'Status', readonly=True),
63         'responsible_id' : fields.many2one('res.users', 'Responsible'),
64         'tot_start_survey' : fields.integer("Total Started Survey", readonly=1),
65         'tot_comp_survey' : fields.integer("Total Completed Survey", readonly=1),
66         'note' : fields.text('Description', size=128),
67         'history' : fields.one2many('survey.history', 'survey_id', 'History Lines', readonly=True),
68         'users': fields.many2many('res.users', 'survey_users_rel', 'sid', 'uid', 'Users'),
69         'send_response' : fields.boolean('E-mail Notification on Response'),
70         'type' : fields.many2one('survey.type', 'Type'),
71     }
72     _defaults = {
73         'state' : lambda * a: "draft",
74         'tot_start_survey' : lambda * a: 0,
75         'tot_comp_survey' : lambda * a: 0,
76         'send_response' : lambda * a: 1,
77         'response_user' : lambda * a:1,
78     }
79
80     def survey_draft(self, cr, uid, ids, arg):
81         self.write(cr, uid, ids, { 'state' : 'draft'})
82         return True
83
84     def survey_open(self, cr, uid, ids, arg):
85         self.write(cr, uid, ids, { 'state' : 'open', 'date_open':strftime("%Y-%m-%d %H:%M:%S")})
86         return True
87
88     def survey_close(self, cr, uid, ids, arg):
89         self.write(cr, uid, ids, { 'state' : 'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S") })
90         return True
91
92     def survey_cancel(self, cr, uid, ids, arg):
93         self.write(cr, uid, ids, { 'state' : 'cancel' })
94         return True
95
96     def copy(self, cr, uid, id, default=None,context={}):
97         raise osv.except_osv(_('Error !'),_('You cannot duplicate the resource!'))
98
99
100 survey()
101
102 class survey_history(osv.osv):
103     _name = 'survey.history'
104     _description = 'Survey History'
105     _rec_name = 'date'
106     _columns = {
107         'survey_id' : fields.many2one('survey', 'Survey'),
108         'user_id' : fields.many2one('res.users', 'User', readonly=True),
109         'date' : fields.datetime('Date started', readonly=1),
110     }
111     _defaults = {
112          'date' : lambda * a: datetime.datetime.now()
113     }
114
115 survey_history()
116
117 class survey_page(osv.osv):
118     _name = 'survey.page'
119     _description = 'Survey Pages'
120     _rec_name = 'title'
121     _order = 'sequence'
122     _columns = {
123         'title' : fields.char('Page Title', size=128, required=1),
124         'survey_id' : fields.many2one('survey', 'Survey', ondelete='cascade'),
125         'question_ids' : fields.one2many('survey.question', 'page_id', 'Question'),
126         'sequence' : fields.integer('Page Nr'),
127         'note' : fields.text('Description'),
128     }
129     _defaults = {
130         'sequence' : lambda * a: 1
131     }
132
133     def default_get(self, cr, uid, fields, context={}):
134         data = super(survey_page, self).default_get(cr, uid, fields, context)
135         if context.has_key('line_order') and context['line_order']:
136             if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'):
137                 data['sequence'] = context['line_order'][-1][2]['sequence'] + 1
138         if context.has_key('survey_id'):
139             data['survey_id'] = context['survey_id']
140         return data
141
142     def survey_save(self, cr, uid, ids, context):
143         search_obj = self.pool.get('ir.ui.view')
144         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
145         surv_name_wiz = self.pool.get('survey.name.wiz')
146         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] })
147         return {
148                 'view_type': 'form',
149                 "view_mode": 'form',
150                 'res_model': 'survey.question.wiz',
151                 'type': 'ir.actions.act_window',
152                 'target': 'new',
153                 'search_view_id':search_id[0],
154                 'context': context
155                 }
156
157     def copy(self, cr, uid, id, default=None,context={}):
158         raise osv.except_osv(_('Error !'),_('You cannot duplicate the resource!'))
159
160 survey_page()
161
162 class survey_question(osv.osv):
163     _name = 'survey.question'
164     _description = 'Survey Question'
165     _rec_name = 'question'
166     _order = 'sequence'
167
168     def _calc_response(self, cr, uid, ids, field_name, arg, context):
169         if len(ids) == 0:
170             return {}
171         val = {}
172         cr.execute("select question_id, count(id) as Total_response from survey_response_line where state='done' and question_id in (%s) group by question_id" % ",".join(map(str, map(int, ids))))
173         ids1 = copy.deepcopy(ids)
174         for rec in  cr.fetchall():
175             ids1.remove(rec[0])
176             val[rec[0]] = int(rec[1])
177         for id in ids1:
178             val[id] = 0
179         return val
180     _columns = {
181         'page_id' : fields.many2one('survey.page', 'Survey Page', ondelete='cascade', required=1),
182         'question' :  fields.char('Question', size=128, required=1),
183         'answer_choice_ids' : fields.one2many('survey.answer', 'question_id', 'Answer'),
184         'response_ids' : fields.one2many('survey.response.line', 'question_id', 'Response', readonly=1),
185         'is_require_answer' : fields.boolean('Require Answer to Question (optional)'),
186         'required_type' : fields.selection([('all','All'), ('at least','At Least'), ('at most','At Most'), ('exactly','Exactly'), ('a range','A Range')], 'Respondent must answer'),
187         'req_ans' : fields.integer('#Required Answer'),
188         'maximum_req_ans' : fields.integer('Maximum Required Answer'),
189         'minimum_req_ans' : fields.integer('Minimum Required Answer'),
190         'req_error_msg' : fields.text('Error Message'),
191         'allow_comment' : fields.boolean('Allow Comment Field'),
192         'sequence' : fields.integer('Sequence'),
193         'tot_resp' : fields.function(_calc_response, method=True, string="Total Response"),
194         'survey' : fields.related('page_id', 'survey_id', type='many2one', relation='survey', string='Survey'),
195         'descriptive_text' : fields.text('Descriptive Text', size=255),
196         'column_heading_ids' : fields.one2many('survey.question.column.heading', 'question_id',' Column heading'),
197         'type' : fields.selection([('multiple_choice_only_one_ans','Multiple Choice (Only One Answer)'),
198                                      ('multiple_choice_multiple_ans','Multiple Choice (Multiple Answer)'),
199                                      ('matrix_of_choices_only_one_ans','Matrix of Choices (Only One Answers Per Row)'),
200                                      ('matrix_of_choices_only_multi_ans','Matrix of Choices (Multiple Answers Per Row)'),
201                                      ('matrix_of_drop_down_menus','Matrix of Drop-down Menus'),
202                                      ('rating_scale','Rating Scale'),('single_textbox','Single Textbox'),
203                                      ('multiple_textboxes','Multiple Textboxes'),
204                                      ('multiple_textboxes_diff_type','Multiple Textboxes With Different Type'),
205                                      ('comment','Comment/Essay Box'),
206                                      ('numerical_textboxes','Numerical Textboxes'),('date','Date'),
207                                      ('date_and_time','Date and Time'),('descriptive_text','Descriptive Text'),
208                                      ('table','Table'),
209                                     ], 'Question Type',  required=1,),
210         'is_comment_require' : fields.boolean('Add Comment Field (optional)'),
211         'comment_label' : fields.char('Field Label', size = 255),
212         'comment_field_type' : fields.selection([('char', 'Single Line Of Text'), ('text', 'Paragraph of Text')], 'Comment Field Type'),
213         'comment_valid_type' : fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''),
214                                                  ('must_be_specific_length', 'Must Be Specific Length'),
215                                                  ('must_be_whole_number', 'Must Be A Whole Number'),
216                                                  ('must_be_decimal_number', 'Must Be A Decimal Number'),
217                                                  ('must_be_date', 'Must Be A Date'),
218                                                  ('must_be_email_address', 'Must Be An Email Address'),
219                                                  ], 'Text Validation'),
220         'comment_minimum_no' : fields.integer('Minimum number'),
221         'comment_maximum_no' : fields.integer('Maximum number'),
222         'comment_minimum_float' : fields.float('Minimum decimal number'),
223         'comment_maximum_float' : fields.float('Maximum decimal number'),
224         'comment_minimum_date' : fields.date('Minimum date'),
225         'comment_maximum_date' : fields.date('Maximum date'),
226         'comment_valid_err_msg' : fields.text('Error message'),
227         'make_comment_field' : fields.boolean('Make Comment Field an Answer Choice'),
228         'make_comment_field_err_msg' : fields.text('Error message'),
229         'is_validation_require' : fields.boolean('Validate Text (optional)'),
230         'validation_type' : fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''),\
231                                                  ('must_be_specific_length', 'Must Be Specific Length'),\
232                                                  ('must_be_whole_number', 'Must Be A Whole Number'),\
233                                                  ('must_be_decimal_number', 'Must Be A Decimal Number'),\
234                                                  ('must_be_date', 'Must Be A Date'),\
235                                                  ('must_be_email_address', 'Must Be An Email Address')\
236                                                  ], 'Text Validation'),
237         'validation_minimum_no' : fields.integer('Minimum number'),
238         'validation_maximum_no' : fields.integer('Maximum number'),
239         'validation_minimum_float' : fields.float('Minimum decimal number'),
240         'validation_maximum_float' : fields.float('Maximum decimal number'),
241         'validation_minimum_date' : fields.date('Minimum date'),
242         'validation_maximum_date' : fields.date('Maximum date'),
243         'validation_valid_err_msg' : fields.text('Error message'),
244         'numeric_required_sum' : fields.integer('Sum of all choices'),
245         'numeric_required_sum_err_msg' : fields.text('Error message'),
246         'rating_allow_one_column_require' : fields.boolean('Allow Only One Response per Column (Forced Ranking)'),
247         'in_visible_rating_weight':fields.boolean('Is Rating Scale Invisible?'),
248         'in_visible_menu_choice':fields.boolean('Is Menu Choice Invisible?'),
249         'in_visible_answer_type':fields.boolean('Is Answer Type Invisible?'),
250         'comment_column':fields.boolean('Add comment column in matrix'),
251         'column_name':fields.char('Column Name',size=256),
252         'no_of_rows' : fields.integer('No of Rows'),
253     }
254     _defaults = {
255          'sequence' : lambda * a: 1,
256          'type' : lambda * a: 'multiple_choice_multiple_ans',
257          'req_error_msg' : lambda * a: 'This question requires an answer.',
258          'required_type' : lambda * a: 'at least',
259          'req_ans' : lambda * a: 1,
260          'comment_field_type' : lambda * a: 'char',
261          'comment_label' : lambda * a: 'Other (please specify)',
262          'comment_valid_type' : lambda * a: 'do_not_validate',
263          'comment_valid_err_msg' : lambda * a : 'The comment you entered is in an invalid format.',
264          'validation_type' : lambda * a: 'do_not_validate',
265          'validation_valid_err_msg' : lambda * a : 'The comment you entered is in an invalid format.',
266          'numeric_required_sum_err_msg' : lambda * a :'The choices need to add up to [enter sum here].',
267          'make_comment_field_err_msg' : lambda * a : 'Please enter a comment.',
268          'in_visible_answer_type' : lambda * a: 1
269     }
270
271     def on_change_type(self, cr, uid, ids, type, context=None):
272         val = {}
273         val['is_require_answer'] = False
274         val['is_comment_require'] = False
275         val['is_validation_require'] = False
276         val['comment_column'] = False
277         if type in ['multiple_textboxes_diff_type']:
278             val['in_visible_answer_type'] = False
279             return {'value': val}
280         if type in ['rating_scale']:
281             val.update({'in_visible_rating_weight':False,'in_visible_menu_choice':True})
282             return {'value': val}
283         elif type in ['matrix_of_drop_down_menus']:
284             val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':False})
285             return {'value': val}
286         elif type in ['single_textbox']:
287             val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':True})
288             return {'value': val}
289         else:
290             val.update({'in_visible_rating_weight':True,'in_visible_menu_choice':True,'in_visible_answer_type':True})
291             return {'value': val}
292
293     def write(self, cr, uid, ids, vals, context=None):
294         questions = self.read(cr,uid, ids, ['answer_choice_ids', 'type', 'required_type','req_ans', 'minimum_req_ans', 'maximum_req_ans', 'column_heading_ids'])
295         for question in questions:
296             col_len = len(question['column_heading_ids'])
297             if vals.has_key('column_heading_ids'):
298                 for col in vals['column_heading_ids']:
299                     if type(col[2]) == type({}):
300                         col_len += 1
301                     else:
302                         col_len -= 1
303             if vals.has_key('type'):
304                 que_type = vals['type']
305             else:
306                 que_type = question['type']
307             if que_type in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']:
308                 if not col_len:
309                     raise osv.except_osv(_('Error !'),_("You must enter one or more column heading."))
310             ans_len = len(question['answer_choice_ids'])
311             if vals.has_key('answer_choice_ids'):
312                 for ans in vals['answer_choice_ids']:
313                     if type(ans[2]) == type({}):
314                         ans_len += 1
315                     else:
316                         ans_len -= 1
317             if que_type not in ['descriptive_text', 'single_textbox', 'comment','table']:
318                 if not ans_len:
319                     raise osv.except_osv(_('Error !'),_("You must enter one or more Answer."))
320             req_type = ""
321             if vals.has_key('required_type'):
322                 req_type = vals['required_type']
323             else:
324                 req_type = question['required_type']
325             if que_type in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
326                 if req_type in ['at least', 'at most', 'exactly']:
327                     if vals.has_key('req_ans'):
328                         if not vals['req_ans'] or  vals['req_ans'] > ans_len:
329                             raise osv.except_osv(_('Error !'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
330                     else:
331                         if not question['req_ans'] or  question['req_ans'] > ans_len:
332                             raise osv.except_osv(_('Error !'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
333                 if req_type == 'a range':
334                     minimum_ans = 0
335                     maximum_ans = 0
336                     if vals.has_key('minimum_req_ans'):
337                         minimum_ans = vals['minimum_req_ans']
338                         if not vals['minimum_req_ans'] or  vals['minimum_req_ans'] > ans_len:
339                             raise osv.except_osv(_('Error !'),_("Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
340                     else:
341                         minimum_ans = question['minimum_req_ans']
342                         if not question['minimum_req_ans'] or  question['minimum_req_ans'] > ans_len:
343                             raise osv.except_osv(_('Error !'),_("Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
344                     if vals.has_key('maximum_req_ans'):
345                         maximum_ans = vals['maximum_req_ans']
346                         if not vals['maximum_req_ans'] or vals['maximum_req_ans'] > ans_len:
347                             raise osv.except_osv(_('Error !'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
348                     else:
349                         maximum_ans = question['maximum_req_ans']
350                         if not question['maximum_req_ans'] or question['maximum_req_ans'] > ans_len:
351                             raise osv.except_osv(_('Error !'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (ans_len + 1))
352                     if maximum_ans <= minimum_ans:
353                         raise osv.except_osv(_('Error !'),_("Maximum Required Answer is greater than Minimum Required Answer"))
354             if question['type'] ==  'matrix_of_drop_down_menus' and vals.has_key('column_heading_ids'):
355                 for col in vals['column_heading_ids']:
356                     if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
357                         raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading"))
358                     elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '':
359                         raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading (white spaces not allowed)"))
360         return super(survey_question, self).write(cr, uid, ids, vals, context=context)
361
362     def create(self, cr, uid, vals, context):
363         minimum_ans = 0
364         maximum_ans = 0
365         if vals.has_key('answer_choice_ids') and  not len(vals['answer_choice_ids']):
366             if vals.has_key('type') and vals['type'] not in ['descriptive_text', 'single_textbox', 'comment','table']:
367                 raise osv.except_osv(_('Error !'),_("You must enter one or more answer."))
368         if vals.has_key('column_heading_ids') and  not len(vals['column_heading_ids']):
369             if vals.has_key('type') and vals['type'] in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']:
370                 raise osv.except_osv(_('Error !'),_("You must enter one or more column heading."))
371         if vals['type'] in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
372             if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] in ['at least', 'at most', 'exactly']:
373                 if vals.has_key('answer_choice_ids') and vals['req_ans'] > len(vals['answer_choice_ids']) or not vals['req_ans']:
374                     raise osv.except_osv(_('Error !'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
375             if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] == 'a range':
376                 minimum_ans = vals['minimum_req_ans']
377                 maximum_ans = vals['maximum_req_ans']
378                 if vals.has_key('answer_choice_ids') or vals['minimum_req_ans'] > len(vals['answer_choice_ids']) or not vals['minimum_req_ans']:
379                     raise osv.except_osv(_('Error !'),_("Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
380                 if vals.has_key('answer_choice_ids') or vals['maximum_req_ans'] > len(vals['answer_choice_ids']) or not vals['maximum_req_ans']:
381                     raise osv.except_osv(_('Error !'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
382                 if maximum_ans <= minimum_ans:
383                     raise osv.except_osv(_('Error !'),_("Maximum Required Answer is greater than Minimum Required Answer"))
384         if vals['type'] ==  'matrix_of_drop_down_menus':
385             for col in vals['column_heading_ids']:
386                 if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
387                     raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading"))
388                 elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '':
389                     raise osv.except_osv(_('Error !'),_("You must enter one or more menu choices in column heading (white spaces not allowed)"))
390         res = super(survey_question, self).create(cr, uid, vals, context)
391         return res
392
393     def survey_save(self, cr, uid, ids, context):
394         search_obj = self.pool.get('ir.ui.view')
395         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
396         surv_name_wiz = self.pool.get('survey.name.wiz')
397         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] })
398         return {
399                 'view_type': 'form',
400                 "view_mode": 'form',
401                 'res_model': 'survey.question.wiz',
402                 'type': 'ir.actions.act_window',
403                 'target': 'new',
404                 'search_view_id':search_id[0],
405                 'context': context
406                 }
407
408     def default_get(self, cr, uid, fields, context={}):
409         data = super(survey_question, self).default_get(cr, uid, fields, context)
410         if context.has_key('line_order') and context['line_order']:
411
412             if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'):
413                 data['sequence'] = context['line_order'][-1][2]['sequence'] + 1
414         if context.has_key('page_id'):
415             data['page_id']= context['page_id']
416         return data
417
418 survey_question()
419
420
421 class survey_question_column_heading(osv.osv):
422     _name = 'survey.question.column.heading'
423     _description = 'Survey Question Column Heading'
424     _rec_name = 'title'
425
426     def _get_in_visible_rating_weight(self,cr, uid, context={}):
427         if context.get('in_visible_rating_weight',False):
428             return context['in_visible_rating_weight']
429         return False
430     def _get_in_visible_menu_choice(self,cr, uid, context={}):
431         if context.get('in_visible_menu_choice',False):
432             return context['in_visible_menu_choice']
433         return False
434
435     _columns = {
436         'title' : fields.char('Column Heading', size=128, required=1),
437         'menu_choice' : fields.text('Menu Choice'),
438         'rating_weight' : fields.integer('Weight'),
439         'question_id' : fields.many2one('survey.question', 'Question', ondelete='cascade'),
440         'in_visible_rating_weight':fields.boolean('Is Rating Scale Invisible ??'),
441         'in_visible_menu_choice':fields.boolean('Is Menu Choice Invisible??')
442     }
443     _defaults={
444        'in_visible_rating_weight':_get_in_visible_rating_weight,
445        'in_visible_menu_choice':_get_in_visible_menu_choice,
446     }
447
448 survey_question_column_heading()
449
450 class survey_answer(osv.osv):
451     _name = 'survey.answer'
452     _description = 'Survey Answer'
453     _rec_name = 'answer'
454     _order = 'sequence'
455
456     def _calc_response_avg(self, cr, uid, ids, field_name, arg, context):
457         val = {}
458         for rec in self.browse(cr, uid, ids):
459             cr.execute("select count(question_id) ,(select count(answer_id) \
460                 from survey_response_answer sra, survey_response_line sa \
461                 where sra.response_id = sa.id and sra.answer_id = %d \
462                 and sa.state='done') as tot_ans from survey_response_line \
463                 where question_id = %d and state = 'done'"\
464                      % (rec.id, rec.question_id.id))
465             res = cr.fetchone()
466             if res[0]:
467                 avg = float(res[1]) * 100 / res[0]
468             else:
469                 avg = 0.0
470             val[rec.id] = {
471                 'response': res[1],
472                 'average': round(avg, 2),
473             }
474         return val
475
476     def _get_in_visible_answer_type(self,cr, uid, context={}):
477         if context.get('in_visible_answer_type',False):
478             return context['in_visible_answer_type']
479         return False
480
481     _columns = {
482         'question_id' : fields.many2one('survey.question', 'Question', ondelete='cascade'),
483         'answer' : fields.char('Answer', size=128, required=1),
484         'sequence' : fields.integer('Sequence'),
485         'response' : fields.function(_calc_response_avg, method=True, string="#Response", multi='sums'),
486         'average' : fields.function(_calc_response_avg, method=True, string="#Avg", multi='sums'),
487         'type' : fields.selection([('char','Character'),('date','Date'),('datetime','Date & Time'),('integer','Integer'),('float','Float'),('selection','Selection'),('email','Email')], "Type of Answer",required=1),
488         'menu_choice' : fields.text('Menu Choices'),
489         'in_visible_answer_type':fields.boolean('Is Answer Type Invisible??')
490     }
491     _defaults = {
492          'sequence' : lambda * a: 1,
493          'type' : lambda * a: 'char',
494          'in_visible_answer_type':_get_in_visible_answer_type,
495     }
496
497     def default_get(self, cr, uid, fields, context={}):
498         data = super(survey_answer, self).default_get(cr, uid, fields, context)
499         if context.has_key('line_order') and context['line_order']:
500             if len(context['line_order'][-1]) > 2 and type(context['line_order'][-1][2]) == type({}) and context['line_order'][-1][2].has_key('sequence'):
501                 data['sequence'] = context['line_order'][-1][2]['sequence'] + 1
502         return data
503
504 survey_answer()
505
506 class survey_response(osv.osv):
507     _name = "survey.response"
508     _rec_name = 'date_create'
509     _columns = {
510         'survey_id' : fields.many2one('survey', 'Survey', required=1, ondelete='cascade'),
511         'date_create' : fields.datetime('Create Date', required=1),
512         'user_id' : fields.many2one('res.users', 'User'),
513         'response_type' : fields.selection([('manually', 'Manually'), ('link', 'Link')], 'Response Type', required=1, readonly=1),
514         'question_ids' : fields.one2many('survey.response.line', 'response_id', 'Response Answer'),
515         'state' : fields.selection([('done', 'Finished '),('skip', 'Not Finished')], 'Status', readonly=True),
516     }
517     _defaults = {
518         'state' : lambda * a: "skip",
519         'response_type' : lambda * a: "manually",
520     }
521
522     def copy(self, cr, uid, id, default=None,context={}):
523         raise osv.except_osv(_('Error !'),_('You cannot duplicate the resource!'))
524
525 survey_response()
526
527 class survey_response_line(osv.osv):
528     _name = 'survey.response.line'
529     _description = 'Survey Response Line'
530     _rec_name = 'date_create'
531     _columns = {
532         'response_id' : fields.many2one('survey.response', 'Response', ondelete='cascade'),
533         'date_create' : fields.datetime('Create Date', required=1),
534         'state' : fields.selection([('draft', 'Draft'), ('done', 'Answered'),('skip', 'Skiped')], 'Status', readonly=True),
535         'question_id' : fields.many2one('survey.question', 'Question'),
536         'page_id' : fields.related('question_id', 'page_id', type='many2one', relation='survey.page', string='Page'),
537         'response_answer_ids' : fields.one2many('survey.response.answer', 'response_id', 'Response Answer'),
538         'response_table_ids' : fields.one2many('survey.tbl.column.heading', 'response_table_id', 'Response Answer'),
539         'comment' : fields.text('Notes'),
540         'single_text' : fields.char('Text', size=255),
541     }
542     _defaults = {
543         'state' : lambda * a: "draft",
544     }
545
546 survey_response_line()
547
548 class survey_tbl_column_heading(osv.osv):
549     _name = 'survey.tbl.column.heading'
550     _order = 'name'
551     _columns = {
552         'name' : fields.integer('Row Number'),
553         'column_id' : fields.many2one('survey.question.column.heading', 'Column'),
554         'value' : fields.char('Value', size = 255),
555         'response_table_id' : fields.many2one('survey.response.line', 'Response', ondelete='cascade'),
556     }
557
558 survey_tbl_column_heading()
559
560 class survey_response_answer(osv.osv):
561     _name = 'survey.response.answer'
562     _description = 'Survey Response Answer'
563     _rec_name = 'response_id'
564     _columns = {
565         'response_id' : fields.many2one('survey.response.line', 'Response', ondelete='cascade'),
566         'answer_id' : fields.many2one('survey.answer', 'Answer', required=1),
567         'column_id' : fields.many2one('survey.question.column.heading','Column'),
568         'answer' : fields.char('Value', size =255),
569         'value_choice' : fields.char('Value Choice', size =255),
570         'comment' : fields.text('Notes'),
571         'comment_field' : fields.char('Comment', size = 255)
572     }
573
574 survey_response_answer()
575
576 class survey_name_wiz(osv.osv_memory):
577     _name = 'survey.name.wiz'
578
579     def default_get(self, cr, uid, fields, context={}):
580         if not context:
581             context = {}
582         data = super(survey_name_wiz, self).default_get(cr, uid, fields, context)
583         if context.has_key('survey_id'):
584             data['survey_id'] = context['survey_id']
585         return data
586
587     def _get_survey(self, cr, uid, context=None):
588         surv_obj = self.pool.get("survey")
589         result = []
590         if context.has_key('survey_id'):
591             for sur in surv_obj.browse(cr, uid, [context['survey_id']]):
592                 result.append((sur.id, sur.title))
593             return result
594         group_id = self.pool.get('res.groups').search(cr, uid, [('name', '=', 'Survey / Manager')])
595         user_obj = self.pool.get('res.users')
596         user_rec = user_obj.read(cr, uid, uid)
597         for sur in surv_obj.browse(cr, uid, surv_obj.search(cr, uid, [])):
598             if sur.state == 'open':
599                 if group_id[0]  in user_rec['groups_id']:
600                     result.append((sur.id, sur.title))
601                 elif sur.id in user_rec['survey_id']:
602                     result.append((sur.id, sur.title))
603         return result
604
605     _columns = {
606         'survey_id': fields.selection(_get_survey, "Survey", required="1"),
607         'page_no' : fields.integer('Page Number'),
608         'note' : fields.text("Description"),
609         'page' : fields.char('Page Position',size = 12),
610         'transfer' : fields.boolean('Page Transfer'),
611         'store_ans' : fields.text('Store Answer'),
612         'response' : fields.char('Response',size=16)
613     }
614     _defaults = {
615         'page_no' : lambda * a: - 1,
616         'page' : lambda * a: 'next',
617         'transfer' : lambda * a: 1,
618         'response' : lambda * a: 0,
619     }
620
621     def action_next(self, cr, uid, ids, context=None):
622         sur_id = self.read(cr, uid, ids, [])[0]
623         survey_id = sur_id['survey_id']
624         context.update({'survey_id' : survey_id, 'sur_name_id' : sur_id['id']})
625         cr.execute('select count(id) from survey_history where user_id=%s\
626                     and survey_id=%s' % (uid,survey_id))
627         res = cr.fetchone()[0]
628         user_limit = self.pool.get('survey').read(cr, uid, survey_id, ['response_user'])['response_user']
629         if user_limit and res >= user_limit:
630             raise osv.except_osv(_('Warning !'),_("You can not give response for this survey more than %s times") % (user_limit))
631         survey_obj = self.pool.get('survey')
632         sur_rec = survey_obj.read(cr,uid,self.read(cr,uid,ids)[0]['survey_id'])
633         if sur_rec['max_response_limit'] and sur_rec['max_response_limit'] <= sur_rec['tot_start_survey']:
634             raise osv.except_osv(_('Warning !'),_("You can not give more response. Please contact the author of this survey for further assistance."))
635         search_obj = self.pool.get('ir.ui.view')
636         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
637         return {
638             'view_type': 'form',
639             "view_mode": 'form',
640             'res_model': 'survey.question.wiz',
641             'type': 'ir.actions.act_window',
642             'target': 'new',
643             'search_view_id':search_id[0],
644             'context' : context
645          }
646
647     def on_change_survey(self, cr, uid, ids, survey_id, context=None):
648         notes = self.pool.get('survey').read(cr, uid, survey_id, ['note'])['note']
649         return {'value': {'note' : notes}}
650
651 survey_name_wiz()
652
653 class survey_question_wiz(osv.osv_memory):
654     _name = 'survey.question.wiz'
655     _columns = {
656         'name': fields.integer('Number'),
657     }
658
659     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
660         result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
661         surv_name_wiz = self.pool.get('survey.name.wiz')
662         if view_type in ['form']:
663             wiz_id = 0
664             if not context.has_key('sur_name_id'):
665                 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context['survey_id'],'page_no' :-1,'page':'next','transfer' :1,'response':0})
666                 sur_name_rec = surv_name_wiz.read(cr, uid, wiz_id, [])
667                 context.update({'sur_name_id' :wiz_id})
668             else:
669                 sur_name_rec = surv_name_wiz.read(cr, uid, context['sur_name_id'])
670
671             if context.has_key('active_id'): context.pop('active_id')
672             survey_id = context['survey_id']
673             survey_obj = self.pool.get('survey')
674             sur_rec = survey_obj.read(cr, uid, survey_id, [])
675             page_obj = self.pool.get('survey.page')
676             que_obj = self.pool.get('survey.question')
677             ans_obj = self.pool.get('survey.answer')
678             response_obj = self.pool.get('survey.response.line')
679             que_col_head = self.pool.get('survey.question.column.heading')
680             p_id = sur_rec['page_ids']
681             total_pages = len(p_id)
682             pre_button = False
683             readonly = 0
684             if context.has_key('response_id'):
685                 readonly = 1
686             if not sur_name_rec['page_no'] + 1 :
687                 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':{}})
688             sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id'])
689             page_number = int(sur_name_rec['page_no'])
690             if sur_name_read['transfer'] or not sur_name_rec['page_no'] + 1:
691                 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
692                 flag = False
693                 fields = {}
694                 if sur_name_read['page'] == "next" or sur_name_rec['page_no'] == - 1 :
695                     if len(p_id) > sur_name_rec['page_no'] + 1 :
696                         if sur_rec['max_response_limit'] and sur_rec['max_response_limit'] <= sur_rec['tot_start_survey'] and not sur_name_rec['page_no'] + 1:
697                             survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
698                         p_id = p_id[sur_name_rec['page_no'] + 1]
699                         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'page_no' : sur_name_rec['page_no'] + 1})
700                         flag = True
701                         page_number += 1
702                     if sur_name_rec['page_no'] > - 1:
703                         pre_button = True
704                 else:
705                     if sur_name_rec['page_no'] != 0:
706                         p_id = p_id[sur_name_rec['page_no'] - 1]
707                         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'page_no' : sur_name_rec['page_no'] - 1})
708                         flag = True
709                         page_number -= 1
710                     if sur_name_rec['page_no'] > 1:
711                         pre_button = True
712                 if flag:
713                     pag_rec = page_obj.read(cr, uid, p_id)
714                     xml_form = etree.Element('form', {'string': _(tools.ustr(pag_rec['title']))})
715                     xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
716                     if wiz_id:
717                         fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
718                         etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0)})
719
720                     if pag_rec['note']:
721                         for que_test in pag_rec['note'].split('\n'):
722                             etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
723                     que_ids = pag_rec['question_ids']
724                     qu_no = 0
725                     for que in que_ids:
726                         qu_no += 1
727                         que_rec = que_obj.read(cr, uid, que)
728                         descriptive_text = ""
729                         separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec['question'])
730                         if not context.has_key('active') and que_rec['is_require_answer']:
731                             star='*'
732                         else:
733                             star=''
734                         xml_group = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '4'})
735                         if context.has_key('active') and context.has_key('edit'):
736                             xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '2'})
737                             etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '3'})
738                             xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
739                             context.update({'question_id' : tools.ustr(que),'page_number' : sur_name_rec['page_no'] , 'transfer' : sur_name_read['transfer'], 'page_id' : p_id})
740                             etree.SubElement(xml_group1, 'button', {'string' :'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
741                             etree.SubElement(xml_group1, 'button', {'string' :'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
742                         else:
743                             xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
744                             etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '4'})
745                         ans_ids = ans_obj.read(cr, uid, que_rec['answer_choice_ids'], [])
746                         xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
747                         if que_rec['type'] == 'multiple_choice_only_one_ans':
748                             selection = []
749                             for ans in ans_ids:
750                                 selection.append((tools.ustr(ans['id']), ans['answer']))
751                             xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
752                             etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_selection"})
753                             fields[tools.ustr(que) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"}
754                         elif que_rec['type'] == 'multiple_choice_multiple_ans':
755                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
756                             for ans in ans_ids:
757                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(ans['id'])})
758                                 fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'boolean', 'string':ans['answer']}
759                         elif que_rec['type'] in ['matrix_of_choices_only_one_ans', 'rating_scale']:
760                             if que_rec['comment_column']:
761                                 col = "4"
762                                 colspan = "4"
763                             else:
764                                col = "2"
765                                colspan = "2"
766                             xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
767                             for row in ans_ids:
768                                 etree.SubElement(xml_group, 'newline')
769                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_selection_" + tools.ustr(row['id']),'string':to_xml(tools.ustr(row['answer']))})
770                                 selection = [('','')]
771                                 for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
772                                     selection.append((str(col['id']), col['title']))
773                                 fields[tools.ustr(que) + "_selection_" + tools.ustr(row['id'])] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
774                                 if que_rec['comment_column']:
775                                    fields[tools.ustr(que) + "_commentcolumn_"+tools.ustr(row['id']) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec['column_name']), 'views':{}}
776                                    etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_commentcolumn_"+tools.ustr(row['id'])+ "_field"})
777                         elif que_rec['type'] == 'matrix_of_choices_only_multi_ans':
778                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids']) + 1), 'colspan': '4'})
779                             etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
780                             for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
781                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col['title']),'colspan': '1'})
782                             for row in ans_ids:
783                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row['answer'])) +' :-', 'align': '0.0'})
784                                 for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
785                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id']), 'nolabel':"1"})
786                                     fields[tools.ustr(que) + "_" + tools.ustr(row['id'])  + "_" + tools.ustr(col['id'])] = {'type':'boolean', 'string': col['title']}
787                         elif que_rec['type'] == 'matrix_of_drop_down_menus':
788                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids']) + 1), 'colspan': '4'})
789                             etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
790                             for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
791                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col['title']),'colspan': '1'})
792                             for row in ans_ids:
793                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row['answer']))+' :-', 'align': '0.0'})
794                                 for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
795                                     selection = []
796                                     if col['menu_choice']:
797                                         for item in col['menu_choice'].split('\n'):
798                                             if item and not item.strip() == '': selection.append((item ,item))
799                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_" + tools.ustr(row['id']) + "_" + tools.ustr(col['id']),'nolabel':'1'})
800                                     fields[tools.ustr(que) + "_" + tools.ustr(row['id'])  + "_" + tools.ustr(col['id'])] = {'type':'selection', 'string': col['title'], 'selection':selection}
801                         elif que_rec['type'] == 'multiple_textboxes':
802                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
803                             type = "char"
804                             if que_rec['is_validation_require']:
805                                 if que_rec['validation_type'] in ['must_be_whole_number']:
806                                     type = "integer"
807                                 elif que_rec['validation_type'] in ['must_be_decimal_number']:
808                                     type = "float"
809                                 elif que_rec['validation_type'] in ['must_be_date']:
810                                     type = "date"
811                             for ans in ans_ids:
812                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"})
813                                 if type == "char" :
814                                     fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'char', 'size':255, 'string':ans['answer']}
815                                 else:
816                                     fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type': str(type), 'string':ans['answer']}
817                         elif que_rec['type'] == 'numerical_textboxes':
818                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
819                             for ans in ans_ids:
820                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_numeric"})
821                                 fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_numeric"] = {'type':'integer', 'string':ans['answer']}
822                         elif que_rec['type'] == 'date':
823                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
824                             for ans in ans_ids:
825                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id'])})
826                                 fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'date', 'string':ans['answer']}
827                         elif que_rec['type'] == 'date_and_time':
828                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
829                             for ans in ans_ids:
830                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id'])})
831                                 fields[tools.ustr(que) + "_" + tools.ustr(ans['id'])] = {'type':'datetime', 'string':ans['answer']}
832                         elif que_rec['type'] == 'descriptive_text':
833                             for que_test in que_rec['descriptive_text'].split('\n'):
834                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
835                         elif que_rec['type'] == 'single_textbox':
836                             etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_single", 'nolabel':"1" ,'colspan':"4"})
837                             fields[tools.ustr(que) + "_single"] = {'type':'char', 'size' : 255, 'string':"single_textbox", 'views':{}}
838                         elif que_rec['type'] == 'comment':
839                             etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_comment", 'nolabel':"1" ,'colspan':"4"})
840                             fields[tools.ustr(que) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
841                         elif que_rec['type'] == 'table':
842                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec['column_heading_ids'])), 'colspan': '4'})
843                             for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
844                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col['title']),'colspan': '1'})
845                             for row in range(0,que_rec['no_of_rows']):
846                                 for col in que_col_head.read(cr, uid, que_rec['column_heading_ids']):
847                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_table_" + tools.ustr(col['id']) +"_"+ tools.ustr(row), 'nolabel':"1"})
848                                     fields[tools.ustr(que) + "_table_" + tools.ustr(col['id']) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
849                         elif que_rec['type'] == 'multiple_textboxes_diff_type':
850                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
851                             for ans in ans_ids:
852                                 if ans['type'] == "email" :
853                                     fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'char', 'size':255, 'string':ans['answer']}
854                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"})
855                                 else:
856                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"})
857                                     if ans['type'] == "char" :
858                                         fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'char', 'size':255, 'string':ans['answer']}
859                                     elif ans['type'] in ['integer','float','date','datetime']:
860                                         fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type': str(ans['type']), 'string':ans['answer']}
861                                     else:
862                                         selection = []
863                                         if ans['menu_choice']:
864                                             for item in ans['menu_choice'].split('\n'):
865                                                 if item and not item.strip() == '': selection.append((item ,item))
866                                         fields[tools.ustr(que) + "_" + tools.ustr(ans['id']) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans['answer']}
867                         if que_rec['type'] in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans', 'matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale'] and que_rec['is_comment_require']:
868                             if que_rec['type'] in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans'] and que_rec['comment_field_type'] in ['char','text'] and que_rec['make_comment_field']:
869                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_otherfield", 'colspan':"4"})
870                                 fields[tools.ustr(que) + "_otherfield"] = {'type':'boolean', 'string':que_rec['comment_label'], 'views':{}}
871                                 if que_rec['comment_field_type'] == 'char':
872                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_other", 'nolabel':"1" ,'colspan':"4"})
873                                     fields[tools.ustr(que) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
874                                 elif que_rec['comment_field_type'] == 'text':
875                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_other", 'nolabel':"1" ,'colspan':"4"})
876                                     fields[tools.ustr(que) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
877                             else:
878                                 if que_rec['comment_field_type'] == 'char':
879                                     etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec['comment_label'])),'colspan':"4"})
880                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_other", 'nolabel':"1" ,'colspan':"4"})
881                                     fields[tools.ustr(que) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
882                                 elif que_rec['comment_field_type'] == 'text':
883                                     etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec['comment_label'])),'colspan':"4"})
884                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que) + "_other", 'nolabel':"1" ,'colspan':"4"})
885                                     fields[tools.ustr(que) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
886                     etree.SubElement(xml_form, 'separator', {'colspan': '4'})
887                     xml_group = etree.SubElement(xml_form, 'group', {'col': '6', 'colspan': '4'})
888                     etree.SubElement(xml_group, 'field', {'name': 'progress_bar_' + tools.ustr(page_number) , 'widget':'progressbar'})
889                     fields['progress_bar_' + tools.ustr(page_number)] = {'type':'float', 'string':"Progress", 'views':{}}
890                     etree.SubElement(xml_group, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages)})
891                     etree.SubElement(xml_group, 'button', {'icon': "gtk-cancel", 'special': "cancel",'string':"Cancel"})
892                     if pre_button:
893                         etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_previous",'string':"Previous",'type':"object"})
894                     etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_next",'string':"Next",'type':"object",'context' : tools.ustr(context)})
895                     if context.has_key('active') and context.has_key('edit'):
896                         etree.SubElement(xml_form, 'separator', {'string' : '','colspan': '4'})
897                         context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec['page_no'] , 'transfer' : sur_name_read['transfer']})
898                         xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
899                         etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
900                         etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
901                         etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
902                         etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
903                     root = xml_form.getroottree()
904                     result['arch'] = etree.tostring(root)
905                     result['fields'] = fields
906                     result['context'] = context
907                 else:
908                     if not context.has_key('active'):
909                         survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec['tot_comp_survey'] + 1})
910                         sur_response_obj = self.pool.get('survey.response')
911                         sur_response_obj.write(cr, uid, [sur_name_read['response']], {'state' : 'done'})
912                         if sur_rec['send_response']:
913                             user_obj = self.pool.get('res.users')
914                             survey_data = survey_obj.browse(cr, uid, int(survey_id))
915                             response_id = surv_name_wiz.read(cr,uid,context['sur_name_id'])['response']
916                             context.update({'response_id':response_id})
917                             report = self.create_report(cr, uid, [int(survey_id)], 'report.survey.browse.response', survey_data.title,context)
918                             attachments = []
919                             file = open(tools.config['addons_path'] + '/survey/report/' + survey_data.title + ".pdf")
920                             file_data = ""
921                             while 1:
922                                 line = file.readline()
923                                 file_data += line
924                                 if not line:
925                                     break
926                             attachments.append((survey_data.title + ".pdf",file_data))
927                             file.close()
928                             os.remove(tools.config['addons_path'] + '/survey/report/' + survey_data.title + ".pdf")
929                             user_email = False
930                             resp_email = False
931                             if user_obj.browse(cr, uid, uid).address_id.id:
932                                 cr.execute("select email from res_partner_address where id =%d" % user_obj.browse(cr, uid, uid).address_id.id)
933                                 user_email = cr.fetchone()[0]
934                             resp_id = survey_data.responsible_id.address_id
935                             if resp_id:
936                                 cr.execute("select email from res_partner_address where id =%d" % resp_id.id)
937                                 resp_email = cr.fetchone()[0]
938                             if user_email and resp_email:
939                                 mail = "Hello " + survey_data.responsible_id.name + ",\n\n " + str(user_obj.browse(cr, uid, uid).name) + " Give Response Of " + survey_data.title + " Survey.\n\n Thanks,"
940                                 tools.email_send(user_email, [resp_email], "Survey Response Of " + str(user_obj.browse(cr, uid, uid).name) , mail, attach = attachments)
941
942                     xml_form = etree.Element('form', {'string': _('Complete Survey Response')})
943                     etree.SubElement(xml_form, 'separator', {'string': 'Complete Survey', 'colspan': "4"})
944                     etree.SubElement(xml_form, 'label', {'string': 'Thanks for your response'})
945                     etree.SubElement(xml_form, 'newline')
946                     etree.SubElement(xml_form, 'button', {'icon': "gtk-go-forward", 'special':"cancel",'string':"OK",'colspan':"2"})
947                     root = xml_form.getroottree()
948                     result['arch'] = etree.tostring(root)
949                     result['fields'] = {}
950                     result['context'] = context
951         return result
952
953     def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
954         if not report_name or not res_ids:
955             return (False, Exception('Report name and Resources ids are required !!!'))
956         try:
957             ret_file_name = tools.config['addons_path'] + '/survey/report/' + file_name + '.pdf'
958             service = netsvc.LocalService(report_name);
959             (result, format) = service.create(cr, uid, res_ids, {}, context)
960             fp = open(ret_file_name, 'wb+');
961             fp.write(result);
962             fp.close();
963         except Exception,e:
964             print 'Exception in create report:',e
965             return (False, str(e))
966         return (True, ret_file_name)
967
968     def default_get(self, cr, uid, fields_list, context=None):
969         value = {}
970         for field in fields_list:
971             if field.split('_')[0] == 'progress':
972                 tot_page_id = self.pool.get('survey').browse(cr, uid, context['survey_id'])
973                 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
974                 value[field] = tot_per
975         if context.has_key('response_id'):
976             response_obj = self.pool.get('survey.response')
977             response_ans = response_obj.browse(cr, uid, context['response_id'])
978             fields_list.sort()
979             for que in response_ans.question_ids:
980                 for field in fields_list:
981                     if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
982                         if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
983                             for ans in que.response_answer_ids:
984                                 if str(field.split('_')[2]) == str(ans.answer_id.id):
985                                     value[field] = ans.comment_field
986                         if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
987                             for ans in que.response_table_ids:
988                                 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) ==  str(ans.name):
989                                     value[field] = ans.value
990                         if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
991                             value[field] = str(que.comment)
992                         elif que.single_text and field.split('_')[1] == "single":
993                             value[field] = str(que.single_text)
994                         elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
995                             for ans in que.response_answer_ids:
996                                 if str(field.split('_')[2]) == str( ans.answer_id.id):
997                                     value[field] = str(ans.column_id.id)
998                         elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
999                             value[field] = str(que.response_answer_ids[0].answer_id.id)
1000                         elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
1001                             for ans in que.response_answer_ids:
1002                                 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
1003                                     if ans.value_choice:
1004                                         value[field] = ans.value_choice
1005                                     else:
1006                                         value[field] = True
1007                         else:
1008                             for ans in que.response_answer_ids:
1009                                 if str(field.split('_')[1]) == str( ans.answer_id.id):
1010                                     value[field] = ans.answer
1011         else:
1012             if not context.has_key('sur_name_id'):
1013                 return value
1014             if context.has_key('active') and context['active']:
1015                 return value
1016             surv_name_wiz = self.pool.get('survey.name.wiz')
1017             sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id'])
1018             ans_list = []
1019             for key,val in sur_name_read['store_ans'].items():
1020                 for field in fields_list:
1021                     if field in list(val):
1022                         value[field] = val[field]
1023         return value
1024
1025     def create(self, cr, uid, vals, context=None):
1026         if context.has_key('active') and context['active']:
1027             return True
1028         for key,val in vals.items():
1029             if key.split('_')[0] == "progress":
1030                 vals.pop(key)
1031             if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
1032                 context.update({'sur_name_id': int(key.split('_')[1])})
1033                 vals.pop(key)
1034         click_state = True
1035         click_update = []
1036         surv_name_wiz = self.pool.get('survey.name.wiz')
1037         surv_all_resp_obj = self.pool.get('survey.response')
1038         surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
1039         sur_name_read = surv_name_wiz.read(cr, uid, context['sur_name_id'], [])
1040         response_id =  0
1041         if not sur_name_read['response']:
1042             response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context['survey_id']})
1043             surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'response' : tools.ustr(response_id)})
1044         else:
1045             response_id = int(sur_name_read['response'])
1046         if response_id not in surv_all_resp_obj.search(cr, uid, []):
1047             response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context['survey_id']})
1048             surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'response' : tools.ustr(response_id)})
1049         #click first time on next button then increemnet on total start suvey
1050         if not sur_name_read['store_ans']:
1051             his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
1052                                               'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id']})
1053             survey_obj = self.pool.get('survey')
1054             sur_rec = survey_obj.read(cr, uid, sur_name_read['survey_id'])
1055             survey_obj.write(cr, uid, sur_name_read['survey_id'],  {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
1056         for key,val in sur_name_read['store_ans'].items():
1057             for field in vals:
1058                 if field.split('_')[0] == val['question_id']:
1059                     click_state = False
1060                     click_update.append(key)
1061                     break
1062         resp_obj = self.pool.get('survey.response.line')
1063         res_ans_obj = self.pool.get('survey.response.answer')
1064         que_obj = self.pool.get('survey.question')
1065         if click_state:
1066             que_li = []
1067             resp_id_list = []
1068             for key, val in vals.items():
1069                 que_id = key.split('_')[0]
1070                 if que_id not in que_li:
1071                     que_li.append(que_id)
1072                     que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
1073                     resp_id = resp_obj.create(cr, uid, {'question_id':que_id, 'date_create':datetime.datetime.now(), \
1074                          'state':'done','response_id' : response_id })
1075                     resp_id_list.append(resp_id)
1076                     sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
1077                     surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1078                     select_count = 0
1079                     numeric_sum = 0
1080                     selected_value = []
1081                     matrix_list = []
1082                     comment_field = False
1083                     comment_value = False
1084                     response_list = []
1085                     for key1, val1 in vals.items():
1086                         if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
1087                             surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
1088                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1089                             select_count += 1
1090                         elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
1091                             comment_field = True
1092                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1093                             select_count += 1
1094                             surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1095                             continue
1096                         elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
1097                             if len(key1.split('_')) > 2:
1098                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
1099                                 selected_value.append(val1)
1100                                 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
1101                             else:
1102                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
1103                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1104                             select_count += 1
1105                         elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
1106                             if not val1:
1107                                 comment_value = True
1108                             else:
1109                                 error = False
1110                                 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
1111                                     if (not val1 and  que_rec['comment_minimum_no']) or len(val1) <  que_rec['comment_minimum_no'] or len(val1) > que_rec['comment_maximum_no']:
1112                                         error = True
1113                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
1114                                     error = False
1115                                     try:
1116                                         if que_rec['comment_valid_type'] == 'must_be_whole_number':
1117                                             value = int(val1)
1118                                             if value <  que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
1119                                                 error = True
1120                                         elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
1121                                             value = float(val1)
1122                                             if value <  que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
1123                                                 error = True
1124                                         elif que_rec['comment_valid_type'] == 'must_be_date':
1125                                             value = datetime.datetime.strptime(val1, "%Y-%m-%d")
1126                                             if value <  datetime.datetime.strptime(que_rec['comment_minimum_date'], "%Y-%m-%d") or value >  datetime.datetime.strptime(que_rec['comment_maximum_date'], "%Y-%m-%d"):
1127                                                 error = True
1128                                     except:
1129                                         error = True
1130                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_email_address':
1131                                     import re
1132                                     if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
1133                                             error = True
1134                                 if error:
1135                                     for res in resp_id_list:
1136                                         sur_name_read['store_ans'].pop(res)
1137                                     raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['comment_valid_err_msg'])))
1138                                 resp_obj.write(cr, uid, resp_id, {'comment':val1})
1139                                 sur_name_read['store_ans'][resp_id].update({key1:val1})
1140                         elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
1141                             resp_obj.write(cr, uid, resp_id, {'comment':val1})
1142                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1143                             select_count += 1
1144                         elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single"  or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
1145                             error = False
1146                             if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
1147                                 if (not val1 and  que_rec['validation_minimum_no']) or len(val1) <  que_rec['validation_minimum_no'] or len(val1) > que_rec['validation_maximum_no']:
1148                                     error = True
1149                             elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
1150                                 error = False
1151                                 try:
1152                                     if que_rec['validation_type'] == 'must_be_whole_number':
1153                                         value = int(val1)
1154                                         if value <  que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
1155                                             error = True
1156                                     elif que_rec['validation_type'] == 'must_be_decimal_number':
1157                                         value = float(val1)
1158                                         if value <  que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
1159                                             error = True
1160                                     elif que_rec['validation_type'] == 'must_be_date':
1161                                         value = datetime.datetime.strptime(val1, "%Y-%m-%d")
1162                                         if value <  datetime.datetime.strptime(que_rec['validation_minimum_date'], "%Y-%m-%d") or value >  datetime.datetime.strptime(que_rec['validation_maximum_date'], "%Y-%m-%d"):
1163                                             error = True
1164                                 except:
1165                                     error = True
1166                             elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
1167                                 import re
1168                                 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
1169                                         error = True
1170                             if error:
1171                                 for res in resp_id_list:
1172                                     sur_name_read['store_ans'].pop(res)
1173                                 raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['validation_valid_err_msg'])))
1174                             if key1.split('_')[1] == "single" :
1175                                 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
1176                             else:
1177                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
1178                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1179                             select_count += 1
1180                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
1181                             if not val1=="0":
1182                                 try:
1183                                     numeric_sum += int(val1)
1184                                     ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
1185                                     sur_name_read['store_ans'][resp_id].update({key1:val1})
1186                                     select_count += 1
1187                                 except:
1188                                     for res in resp_id_list:
1189                                         sur_name_read['store_ans'].pop(res)
1190                                     raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' \nPlease enter an integer value " ))
1191
1192                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
1193                             if type(val1) == type('') or type(val1) == type(u''):
1194                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2], 'value_choice' : val1})
1195                                 sur_name_read['store_ans'][resp_id].update({key1:val1})
1196                             else:
1197                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
1198                                 sur_name_read['store_ans'][resp_id].update({key1:True})
1199                             matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
1200                             select_count += 1
1201                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
1202                             ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
1203                             sur_name_read['store_ans'][resp_id].update({key1:val1})
1204                             select_count += 1
1205                         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1206                     for key,val in vals.items():
1207                         if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
1208                             for res_id in response_list:
1209                                 if key.split('_')[2] in res_id.split('_')[1]:
1210                                     a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
1211                                     sur_name_read['store_ans'][resp_id].update({key:val})
1212                     if comment_field and comment_value:
1213                         for res in resp_id_list:
1214                             sur_name_read['store_ans'].pop(res)
1215                         raise osv.except_osv(_('Error re !'), _("'" + que_rec['question']  + "' " + tools.ustr(que_rec['make_comment_field_err_msg'])))
1216                     if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
1217                         for res in resp_id_list:
1218                             sur_name_read['store_ans'].pop(res)
1219                         raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'"))
1220                     if not select_count:
1221                         resp_obj.write(cr, uid, resp_id, {'state':'skip'})
1222                     if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
1223                         for res in resp_id_list:
1224                             sur_name_read['store_ans'].pop(res)
1225                         raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg'])))
1226                     if que_rec['type'] in ['multiple_textboxes_diff_type', 'multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']:
1227                         if matrix_list:
1228                             if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
1229                             (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
1230                             (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
1231                             (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
1232                             (que_rec['required_type'] == 'a range' and (len(list(set(matrix_list))) < que_rec['minimum_req_ans'] or len(list(set(matrix_list))) > que_rec['maximum_req_ans'])):
1233                                 for res in resp_id_list:
1234                                     sur_name_read['store_ans'].pop(res)
1235                                 raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1236                         elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
1237                             (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
1238                             (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1239                             (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1240                             (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1241                             for res in resp_id_list:
1242                                 sur_name_read['store_ans'].pop(res)
1243                             raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1244                     if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and  que_rec['is_require_answer'] and select_count <= 0:
1245                         for res in resp_id_list:
1246                             sur_name_read['store_ans'].pop(res)
1247                         raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1248         else:
1249             resp_id_list = []
1250             for update in click_update:
1251                 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
1252                 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
1253                 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
1254                 resp_id_list.append(update)
1255                 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
1256                 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1257                 select_count = 0
1258                 numeric_sum = 0
1259                 selected_value = []
1260                 matrix_list = []
1261                 comment_field = False
1262                 comment_value = False
1263                 response_list = []
1264                 for key, val in vals.items():
1265                     ans_id_len = key.split('_')
1266                     if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
1267                         if val and key.split('_')[1] == "table":
1268                             surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
1269                             sur_name_read['store_ans'][update].update({key:val})
1270                             resp_obj.write(cr, uid, update, {'state': 'done'})
1271                         elif val and key.split('_')[1] == "otherfield" :
1272                             comment_field = True
1273                             sur_name_read['store_ans'][update].update({key:val})
1274                             select_count += 1
1275                             surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1276                             continue
1277                         elif val and key.split('_')[1] == "selection":
1278                             if len(key.split('_')) > 2:
1279                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
1280                                 selected_value.append(val)
1281                                 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
1282                             else:
1283                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
1284                             resp_obj.write(cr, uid, update, {'state': 'done'})
1285                             sur_name_read['store_ans'][update].update({key:val})
1286                             select_count += 1
1287                         elif key.split('_')[1] == "other":
1288                             if not val:
1289                                 comment_value = True
1290                             else:
1291                                 error = False
1292                                 if que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_specific_length':
1293                                     if (not val and  que_rec['comment_minimum_no']) or len(val) <  que_rec['comment_minimum_no'] or len(val) > que_rec['comment_maximum_no']:
1294                                         error = True
1295                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
1296                                     try:
1297                                         if que_rec['comment_valid_type'] == 'must_be_whole_number':
1298                                             value = int(val)
1299                                             if value <  que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
1300                                                 error = True
1301                                         elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
1302                                             value = float(val)
1303                                             if value <  que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
1304                                                 error = True
1305                                         elif que_rec['comment_valid_type'] == 'must_be_date':
1306                                             value = datetime.datetime.strptime(val, "%Y-%m-%d")
1307                                             if value <  datetime.datetime.strptime(que_rec['comment_minimum_date'], "%Y-%m-%d") or value >  datetime.datetime.strptime(que_rec['comment_maximum_date'], "%Y-%m-%d"):
1308                                                 error = True
1309                                     except:
1310                                         error = True
1311                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_email_address':
1312                                     import re
1313                                     if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
1314                                             error = True
1315                                 if error:
1316                                     raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['comment_valid_err_msg'])))
1317                                 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
1318                                 sur_name_read['store_ans'][update].update({key:val})
1319                         elif val and key.split('_')[1] == "comment":
1320                             resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
1321                             sur_name_read['store_ans'][update].update({key:val})
1322                             select_count += 1
1323                         elif val and (key.split('_')[1] == "single"  or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
1324                             error = False
1325                             if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
1326                                 if (not val and  que_rec['validation_minimum_no']) or len(val) <  que_rec['validation_minimum_no'] or len(val) > que_rec['validation_maximum_no']:
1327                                     error = True
1328                             elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
1329                                 error = False
1330                                 try:
1331                                     if que_rec['validation_type'] == 'must_be_whole_number':
1332                                         value = int(val)
1333                                         if value <  que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
1334                                             error = True
1335                                     elif que_rec['validation_type'] == 'must_be_decimal_number':
1336                                         value = float(val)
1337                                         if value <  que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
1338                                             error = True
1339                                     elif que_rec['validation_type'] == 'must_be_date':
1340                                         value = datetime.datetime.strptime(val, "%Y-%m-%d")
1341                                         if value <  datetime.datetime.strptime(que_rec['validation_minimum_date'], "%Y-%m-%d") or value >  datetime.datetime.strptime(que_rec['validation_maximum_date'], "%Y-%m-%d"):
1342                                             error = True
1343                                 except Exception ,e:
1344                                     error = True
1345                             elif que_rec['is_validation_require'] and  que_rec['validation_type'] == 'must_be_email_address':
1346                                 import re
1347                                 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
1348                                         error = True
1349                             if error:
1350                                 raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['validation_valid_err_msg'])))
1351                             if key.split('_')[1] == "single" :
1352                                 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
1353                             else:
1354                                 resp_obj.write(cr, uid, update, {'state': 'done'})
1355                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
1356                             sur_name_read['store_ans'][update].update({key:val})
1357                             select_count += 1
1358                         elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
1359                             if not val=="0":
1360                                 try:
1361                                     numeric_sum += int(val)
1362                                     resp_obj.write(cr, uid, update, {'state': 'done'})
1363                                     ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
1364                                     sur_name_read['store_ans'][update].update({key:val})
1365                                     select_count += 1
1366                                 except:
1367                                     raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' \n Please enter an integer value " ))
1368
1369                         elif val and len(key.split('_')) == 3:
1370                             resp_obj.write(cr, uid, update, {'state': 'done'})
1371                             if type(val) == type('') or type(val) == type(u''):
1372                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2], 'value_choice' : val})
1373                                 sur_name_read['store_ans'][update].update({key:val})
1374                             else:
1375                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
1376                                 sur_name_read['store_ans'][update].update({key:True})
1377                             matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
1378                             select_count += 1
1379                         elif val and len(key.split('_')) == 2:
1380                             resp_obj.write(cr, uid, update, {'state': 'done'})
1381                             ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[-1], 'answer' : val})
1382                             sur_name_read['store_ans'][update].update({key:val})
1383                             select_count += 1
1384                         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'store_ans':sur_name_read['store_ans']})
1385                 for key,val in vals.items():
1386                     if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
1387                         for res_id in response_list:
1388                             if key.split('_')[2] in res_id.split('_')[1]:
1389                                 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
1390                                 sur_name_read['store_ans'][update].update({key:val})
1391                 if comment_field and comment_value:
1392                     raise osv.except_osv(_('Error re !'), _("'" + que_rec['question']  + "' " + tools.ustr(que_rec['make_comment_field_err_msg'])))
1393                 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
1394                     raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'"))
1395                 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
1396                     raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg'])))
1397                 if not select_count:
1398                     resp_obj.write(cr, uid, update, {'state': 'skip'})
1399                 if que_rec['type'] in ['multiple_textboxes_diff_type','multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']:
1400                     if matrix_list:
1401                         if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
1402                         (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
1403                         (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
1404                         (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
1405                         (que_rec['required_type'] == 'a range' and (len(list(set(matrix_list))) < que_rec['minimum_req_ans'] or len(list(set(matrix_list))) > que_rec['maximum_req_ans'])):
1406                             raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1407                     elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
1408                         (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
1409                         (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1410                         (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1411                         (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1412                             raise osv.except_osv(_('Error !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1413                 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and  que_rec['is_require_answer'] and select_count <= 0:
1414                     raise osv.except_osv(_('Error re !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1415         return True
1416
1417     def action_new_question(self,cr, uid, ids, context):
1418         for key,val in context.items():
1419             if type(key) == type(True):
1420                 context.pop(key)
1421         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),('name','=','survey_question_wizard_test')])
1422         return {
1423                 'view_type': 'form',
1424                 "view_mode": 'form',
1425                 'res_model': 'survey.question',
1426                 'type': 'ir.actions.act_window',
1427                 'target': 'new',
1428                 'view_id': view_id,
1429                 'context': context
1430                 }
1431
1432     def action_new_page(self, cr, uid, ids, context):
1433         for key,val in context.items():
1434             if type(key) == type(True):
1435                 context.pop(key)
1436         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),('name','=','survey_page_wizard_test')])
1437         return {
1438                 'view_type': 'form',
1439                 "view_mode": 'form',
1440                 'res_model': 'survey.page',
1441                 'type': 'ir.actions.act_window',
1442                 'target': 'new',
1443                 'view_id': view_id,
1444                 'context': context
1445                 }
1446
1447     def action_edit_page(self,cr, uid, ids, context):
1448         for key,val in context.items():
1449             if type(key) == type(True):
1450                 context.pop(key)
1451         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),('name','=','survey_page_wizard_test')])
1452         return {
1453                 'view_type': 'form',
1454                 "view_mode": 'form',
1455                 'res_model': 'survey.page',
1456                 'type': 'ir.actions.act_window',
1457                 'target': 'new',
1458                 'res_id' : int(context['page_id']),
1459                 'view_id': view_id,
1460                 'context': context
1461                 }
1462
1463     def action_delete_page(self,cr, uid, ids, context):
1464         for key,val in context.items():
1465             if type(key) == type(True):
1466                 context.pop(key)
1467         self.pool.get('survey.page').unlink(cr, uid, [context['page_id']])
1468         search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1469         surv_name_wiz = self.pool.get('survey.name.wiz')
1470         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] })
1471         return {
1472                 'view_type': 'form',
1473                 "view_mode": 'form',
1474                 'res_model': 'survey.question.wiz',
1475                 'type': 'ir.actions.act_window',
1476                 'target': 'new',
1477                 'search_view_id':search_id[0],
1478                 'context': context
1479                 }
1480
1481     def action_edit_question(self,cr, uid, ids, context):
1482         for key,val in context.items():
1483             if type(key) == type(True):
1484                 context.pop(key)
1485         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),('name','=','survey_question_wizard_test')])
1486         return {
1487                 'view_type': 'form',
1488                 "view_mode": 'form',
1489                 'res_model': 'survey.question',
1490                 'type': 'ir.actions.act_window',
1491                 'target': 'new',
1492                 'res_id' : int(context['question_id']),
1493                 'view_id': view_id,
1494                 'context': context
1495                 }
1496
1497     def action_delete_question(self,cr, uid, ids, context):
1498         for key,val in context.items():
1499             if type(key) == type(True):
1500                 context.pop(key)
1501         que_obj = self.pool.get('survey.question')
1502         que_obj.unlink(cr, uid, [context['question_id']])
1503         search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1504         surv_name_wiz = self.pool.get('survey.name.wiz')
1505         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page_no' : context['page_number'] })
1506         return {
1507                 'view_type': 'form',
1508                 "view_mode": 'form',
1509                 'res_model': 'survey.question.wiz',
1510                 'type': 'ir.actions.act_window',
1511                 'target': 'new',
1512                 'search_view_id':search_id[0],
1513                 'context': context
1514                 }
1515
1516     def action_next(self, cr, uid, ids, context=None):
1517         surv_name_wiz = self.pool.get('survey.name.wiz')
1518         search_obj = self.pool.get('ir.ui.view')
1519         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1520         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page':'next'})
1521         return {
1522                 'view_type': 'form',
1523                 "view_mode": 'form',
1524                 'res_model': 'survey.question.wiz',
1525                 'type': 'ir.actions.act_window',
1526                 'target': 'new',
1527                 'search_view_id':search_id[0],
1528                 'context': context
1529                 }
1530
1531     def action_previous(self, cr, uid, ids, context=None):
1532         surv_name_wiz = self.pool.get('survey.name.wiz')
1533         search_obj = self.pool.get('ir.ui.view')
1534         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1535         surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':True, 'page':'previous'})
1536         return {
1537                 'view_type': 'form',
1538                 "view_mode": 'form',
1539                 'res_model': 'survey.question.wiz',
1540                 'type': 'ir.actions.act_window',
1541                 'target': 'new',
1542                 'search_view_id':search_id[0],
1543                 'context': context
1544                 }
1545
1546 survey_question_wiz()
1547
1548 class res_users(osv.osv):
1549     _inherit = "res.users"
1550     _name = "res.users"
1551     _columns = {
1552         'survey_id': fields.many2many('survey', 'survey_users_rel', 'uid', 'sid', 'Groups'),
1553     }
1554
1555 res_users()
1556
1557 class survey_request(osv.osv):
1558     _name = "survey.request"
1559     _order = 'date_deadline'
1560     _rec_name = 'date_deadline'
1561     _columns = {
1562         'date_deadline' : fields.date("Deadline date"),
1563         'user_id' : fields.many2one("res.users", "User"),
1564         'email' : fields.char("E-mail", size=64),
1565         'survey_id' : fields.many2one("survey", "Survey", required=1),
1566         'answer_ids' : fields.one2many('survey.answer', 'question_id', 'Answer'),
1567         'state' : fields.selection([('waiting_answer', 'Wating Answer'),('done', 'Done'),('cancel', 'Cancelled')], 'State', readonly=1)
1568     }
1569     _defaults = {
1570         'state' : lambda * a: 'waiting_answer',
1571         'date_deadline' : lambda * a :  (now() + RelativeDateTime(months=+1)).strftime("%Y-%m-%d %H:%M:%S")
1572     }
1573     def survey_req_waiting_answer(self, cr, uid, ids, arg):
1574         self.write(cr, uid, ids, { 'state' : 'waiting_answer'})
1575         return True
1576
1577     def survey_req_done(self, cr, uid, ids, arg):
1578         self.write(cr, uid, ids, { 'state' : 'done'})
1579         return True
1580
1581     def survey_req_cancel(self, cr, uid, ids, arg):
1582         self.write(cr, uid, ids, { 'state' : 'cancel'})
1583         return True
1584
1585     def on_change_user(self, cr, uid, ids, user_id, context=None):
1586         if user_id:
1587             user_obj = self.pool.get('res.users')
1588             user = user_obj.browse(cr, uid, user_id)
1589             return {'value': {'email': user.address_id.email}}
1590         return {}
1591
1592 survey_request()
1593
1594
1595 class survey_print_answer(osv.osv_memory):
1596     _name = 'survey.print.answer'
1597
1598     def _get_survey(self, cr, uid, context=None):
1599         surv_obj = self.pool.get("survey")
1600         surv_resp_obj = self.pool.get("survey.response")
1601         result = []
1602         for sur in surv_obj.browse(cr, uid, surv_obj.search(cr, uid, [])):
1603             if surv_resp_obj.search(cr, uid, [('survey_id', '=', sur.id)]):
1604                 result.append((sur.id, sur.title))
1605         return result
1606
1607     _columns = {
1608         'survey_id': fields.selection(_get_survey, "Survey", required="1"),
1609         'response_id': fields.many2one("survey.response", "Survey Response", required="1"),
1610     }
1611
1612     def action_next(self, cr, uid, ids, context=None):
1613         response_id = self.read(cr, uid, ids, [])[0]
1614         context.update({'active' : True,'survey_id' : response_id['survey_id'], 'response_id' : response_id['response_id']})
1615         search_obj = self.pool.get('ir.ui.view')
1616         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1617         return {
1618             'view_type': 'form',
1619             "view_mode": 'form',
1620             'res_model': 'survey.question.wiz',
1621             'type': 'ir.actions.act_window',
1622             'target': 'new',
1623             'search_view_id':search_id[0],
1624             'context' : context
1625          }
1626
1627 survey_print_answer()
1628
1629 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: