1 ## -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
23 from lxml import etree
24 from time import strftime
30 from osv import fields
31 from tools import to_xml
32 from tools.translate import _
34 from tools.safe_eval import safe_eval
36 class survey_question_wiz(osv.osv_memory):
37 _name = 'survey.question.wiz'
39 'name': fields.integer('Number'),
42 def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
44 Fields View Get method :- generate the new view and display the survey pages of selected survey.
48 result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
49 view_type, context, toolbar,submenu)
51 surv_name_wiz = self.pool.get('survey.name.wiz')
52 survey_obj = self.pool.get('survey')
53 page_obj = self.pool.get('survey.page')
54 que_obj = self.pool.get('survey.question')
55 ans_obj = self.pool.get('survey.answer')
56 sur_response_obj = self.pool.get('survey.response')
57 que_col_head = self.pool.get('survey.question.column.heading')
58 user_obj = self.pool.get('res.users')
59 mail_message = self.pool.get('mail.message')
61 if view_type in ['form']:
64 if 'sur_name_id' in context:
65 sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
66 elif 'survey_id' in context:
68 'survey_id': context.get('survey_id', False),
74 wiz_id = surv_name_wiz.create(cr, uid, res_data)
75 sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id, context=context)
76 context.update({'sur_name_id' :wiz_id})
78 if context.has_key('active_id'):
79 context.pop('active_id')
81 survey_id = context.get('survey_id', False)
83 # Try one more time to find it
84 if sur_name_rec and sur_name_rec.survey_id:
85 survey_id = sur_name_rec.survey_id.id
87 # raise osv.except_osv(_('Error!'), _("Cannot locate survey for the question wizard!"))
88 # If this function is called without a survey_id in
89 # its context, it makes no sense to return any view.
90 # Just return the default, empty view for this object,
91 # in order to please random calls to this fn().
92 return super(survey_question_wiz, self).\
93 fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context,
94 toolbar=toolbar, submenu=submenu)
95 sur_rec = survey_obj.browse(cr, uid, survey_id, context=context)
96 p_id = map(lambda x:x.id, sur_rec.page_ids)
97 total_pages = len(p_id)
101 if context.get('response_id', False) \
102 and int(context['response_id'][0]) > 0:
105 if not sur_name_rec.page_no + 1 :
106 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
108 sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
109 page_number = int(sur_name_rec.page_no)
110 if sur_name_read.transfer or not sur_name_rec.page_no + 1:
111 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
114 if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
115 if total_pages > sur_name_rec.page_no + 1:
116 if ((context.has_key('active') and not context.get('active', False)) \
117 or not context.has_key('active')) and not sur_name_rec.page_no + 1:
118 if sur_rec.state != "open" :
119 raise osv.except_osv(_('Warning!'),_("You cannot answer because the survey is not open."))
120 cr.execute('select count(id) from survey_history where user_id=%s\
121 and survey_id=%s', (uid,survey_id))
122 res = cr.fetchone()[0]
123 user_limit = survey_obj.browse(cr, uid, survey_id)
124 user_limit = user_limit.response_user
125 if user_limit and res >= user_limit:
126 raise osv.except_osv(_('Warning!'),_("You cannot answer this survey more than %s times.") % (user_limit))
128 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:
129 survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
131 p_id = p_id[sur_name_rec.page_no + 1]
132 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
135 if sur_name_rec.page_no > - 1:
138 if sur_name_rec.page_no != 0:
139 p_id = p_id[sur_name_rec.page_no - 1]
140 surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
141 {'page_no' : sur_name_rec.page_no - 1})
145 if sur_name_rec.page_no > 1:
148 pag_rec = page_obj.browse(cr, uid, p_id, context=context)
149 xml_form = etree.Element('form', {'string': tools.ustr(pag_rec.title)})
150 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
151 if context.has_key('response_id') and context.get('response_id', False) \
152 and int(context.get('response_id',0)[0]) > 0:
153 # TODO: l10n, cleanup this code to make it readable. Or template?
154 xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
155 record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
156 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr('Answer Of :- ' + record.user_id.name + ', Date :- ' + record.date_create.split('.')[0] )), 'align':"0.0"})
157 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(" Answer :- " + str(context.get('response_no',0) + 1) +"/" + str(len(context.get('response_id',0))) )), 'align':"0.0"})
158 if context.get('response_no',0) > 0:
159 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
160 if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
161 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)})
164 fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
165 etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0)})
168 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
169 for que_test in pag_rec.note.split('\n'):
170 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
171 que_ids = pag_rec.question_ids
176 que_rec = que_obj.browse(cr, uid, que.id, context=context)
177 descriptive_text = ""
178 separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
179 if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
183 xml_group = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '4'})
185 if context.has_key('active') and context.get('active',False) and \
186 context.has_key('edit'):
187 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '2'})
188 etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '3'})
189 xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
190 context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
191 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
192 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
194 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
195 etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '4'})
197 ans_ids = que_rec.answer_choice_ids
198 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
200 if que_rec.type == 'multiple_choice_only_one_ans':
203 selection.append((tools.ustr(ans.id), ans.answer))
204 xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
205 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
206 fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"}
208 elif que_rec.type == 'multiple_choice_multiple_ans':
209 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
211 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
212 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
214 elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
215 if que_rec.comment_column:
221 xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
223 etree.SubElement(xml_group, 'newline')
224 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'name': tools.ustr(que.id) + "_selection_" + tools.ustr(row.id),'string':to_xml(tools.ustr(row.answer))})
225 selection = [('','')]
226 for col in que_rec.column_heading_ids:
227 selection.append((str(col.id), col.title))
228 fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
229 if que_rec.comment_column:
230 fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
231 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
233 elif que_rec.type == 'matrix_of_choices_only_multi_ans':
234 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
235 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
236 for col in que_rec.column_heading_ids:
237 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
239 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
240 for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
241 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
242 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
244 elif que_rec.type == 'matrix_of_drop_down_menus':
245 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
246 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
247 for col in que_rec.column_heading_ids:
248 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
250 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
251 for col in que_rec.column_heading_ids:
254 for item in col.menu_choice.split('\n'):
255 if item and not item.strip() == '': selection.append((item ,item))
256 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
257 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
259 elif que_rec.type == 'multiple_textboxes':
260 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
262 if que_rec.is_validation_require:
263 if que_rec.validation_type in ['must_be_whole_number']:
265 elif que_rec.validation_type in ['must_be_decimal_number']:
267 elif que_rec.validation_type in ['must_be_date']:
270 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
272 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
274 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
276 elif que_rec.type == 'numerical_textboxes':
277 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
279 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
280 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
282 elif que_rec.type == 'date':
283 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
285 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
286 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
288 elif que_rec.type == 'date_and_time':
289 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
291 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
292 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
294 elif que_rec.type == 'descriptive_text':
295 if que_rec.descriptive_text:
296 for que_test in que_rec.descriptive_text.split('\n'):
297 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
299 elif que_rec.type == 'single_textbox':
300 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
301 fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
303 elif que_rec.type == 'comment':
304 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
305 fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
307 elif que_rec.type == 'table':
308 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
309 for col in que_rec.column_heading_ids:
310 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
311 for row in range(0,que_rec.no_of_rows):
312 for col in que_rec.column_heading_ids:
313 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
314 fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
316 elif que_rec.type == 'multiple_textboxes_diff_type':
317 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
319 if ans.type == "email" :
320 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
321 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
323 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
324 if ans.type == "char" :
325 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
326 elif ans.type in ['integer','float','date','datetime']:
327 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
331 for item in ans.menu_choice.split('\n'):
332 if item and not item.strip() == '': selection.append((item ,item))
333 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
335 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:
336 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:
337 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
338 fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
339 if que_rec.comment_field_type == 'char':
340 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
341 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
342 elif que_rec.comment_field_type == 'text':
343 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
344 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
346 if que_rec.comment_field_type == 'char':
347 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
348 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
349 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
350 elif que_rec.comment_field_type == 'text':
351 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
352 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
353 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
355 etree.SubElement(xml_form, 'separator', {'colspan': '4'})
356 xml_group = etree.SubElement(xml_form, 'group', {'col': '6', 'colspan': '4'})
357 etree.SubElement(xml_group, 'field', {'name': 'progress_bar_' + tools.ustr(page_number) , 'widget':'progressbar'})
358 fields['progress_bar_' + tools.ustr(page_number)] = {'type':'float', 'string':"Progress", 'views':{}}
359 etree.SubElement(xml_group, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages)})
360 etree.SubElement(xml_group, 'button', {'icon': "gtk-cancel", 'special': "cancel",'string':"Cancel"})
363 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_previous",'string':"Previous",'type':"object"})
365 if int(page_number) + 1 == total_pages:
368 if context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context.get('response_no',0) + 1 == len(context.get('response_id',0)):
369 etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context)})
370 elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
371 etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)})
372 elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
373 etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context)})
375 etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context)})
377 if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
378 etree.SubElement(xml_form, 'separator', {'string' : '','colspan': '4'})
379 context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
380 xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
381 etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
382 etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
383 etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
384 etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
386 root = xml_form.getroottree()
387 result['arch'] = etree.tostring(root)
388 result['fields'] = fields
389 result['context'] = context
391 survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
392 sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
394 # mark the survey request as done; call 'survey_req_done' on its actual model
395 survey_req_obj = self.pool.get(context.get('active_model'))
396 if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
397 survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
399 if sur_rec.send_response:
400 survey_data = survey_obj.browse(cr, uid, survey_id)
401 response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
402 context.update({'response_id':response_id})
403 report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
405 file = open(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
408 line = file.readline()
413 attachments[survey_data.title + ".pdf"] = file_data
415 os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
417 user_email = user_obj.browse(cr, uid, uid, context).email
418 resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
420 if user_email and resp_email:
421 user_name = user_obj.browse(cr, uid, uid, context=context).name
422 mail = "Hello " + survey_data.responsible_id.name + ",\n\n " + str(user_name) + " has given the Response Of " + survey_data.title + " Survey.\nThe Response has been attached herewith.\n\n Thanks."
423 mail_message.schedule_with_attach(cr, uid, user_email, [resp_email], "Survey Answer Of " + str(user_name) , mail, attachments=attachments, context=context)
425 xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
426 etree.SubElement(xml_form, 'separator', {'string': 'Complete Survey', 'colspan': "4"})
427 etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
428 etree.SubElement(xml_form, 'newline')
429 etree.SubElement(xml_form, 'button', {'icon': "gtk-go-forward", 'special':"cancel",'string':"OK",'colspan':"2"})
430 root = xml_form.getroottree()
431 result['arch'] = etree.tostring(root)
432 result['fields'] = {}
433 result['context'] = context
436 def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
438 If any user give answer of survey then last create report of this answer and if 'Email Notification on Answer' set True in survey then send mail on responsible person of this survey and attach survey answer report in pdf format.
440 if not report_name or not res_ids:
441 return (False, Exception('Report name and Resources ids are required !!!'))
444 service = netsvc.LocalService(report_name);
445 (result, format) = service.create(cr, uid, res_ids, {}, context)
446 ret_file_name = addons.get_module_resource('survey', 'report') + file_name + '.pdf'
447 fp = open(ret_file_name, 'wb+');
451 # hr.applicant: if survey answered directly in system: attach report to applicant
452 if context.get('active_model') == 'hr.applicant':
453 self.pool.get('hr.applicant').write(cr,uid,[context.get('active_ids')[0]],{'response':context.get('response_id')})
454 result = base64.b64encode(result)
455 file_name = file_name + '.pdf'
456 ir_attachment = self.pool.get('ir.attachment').create(cr, uid,
459 'datas_fname': file_name,
460 'res_model': context.get('active_model'),
461 'res_id': context.get('active_ids')[0]},
465 return (False, str(e))
467 return (True, ret_file_name)
469 def default_get(self, cr, uid, fields_list, context=None):
471 Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
476 for field in fields_list:
477 if field.split('_')[0] == 'progress':
478 tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
479 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
480 value[field] = tot_per
481 response_obj = self.pool.get('survey.response')
482 surv_name_wiz = self.pool.get('survey.name.wiz')
484 if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
485 data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
486 response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
489 for que in response_ans.question_ids:
490 for field in fields_list:
491 if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
492 if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
493 for ans in que.response_answer_ids:
494 if str(field.split('_')[2]) == str(ans.answer_id.id):
495 value[field] = ans.comment_field
497 if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
498 for ans in que.response_table_ids:
499 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name):
500 value[field] = ans.value
502 if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
503 value[field] = str(que.comment)
505 elif que.single_text and field.split('_')[1] == "single":
506 value[field] = str(que.single_text)
508 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
509 for ans in que.response_answer_ids:
510 if str(field.split('_')[2]) == str( ans.answer_id.id):
511 value[field] = str(ans.column_id.id)
513 elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
514 value[field] = str(que.response_answer_ids[0].answer_id.id)
516 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
517 for ans in que.response_answer_ids:
518 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
520 value[field] = ans.value_choice
525 for ans in que.response_answer_ids:
526 if str(field.split('_')[1]) == str( ans.answer_id.id):
527 value[field] = ans.answer
530 if not context.has_key('sur_name_id'):
532 if context.has_key('active') and context.get('active',False):
535 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
538 for key,val in safe_eval(sur_name_read.get('store_ans',"{}")).items():
539 for field in fields_list:
540 if field in list(val):
541 value[field] = val[field]
545 def create(self, cr, uid, vals, context=None):
547 Create the Answer of survey and store in survey.response object, and if set validation of question then check the value of question if value is wrong then raise the exception.
549 if context is None: context = {}
551 survey_question_wiz_id = super(survey_question_wiz,self).create(cr, uid, {'name': vals.get('name')}, context=context)
552 if context.has_key('active') and context.get('active',False):
553 return survey_question_wiz_id
555 for key,val in vals.items():
556 if key.split('_')[0] == "progress":
558 if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
559 context.update({'sur_name_id': int(key.split('_')[1])})
564 surv_name_wiz = self.pool.get('survey.name.wiz')
565 surv_all_resp_obj = self.pool.get('survey.response')
566 surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
567 survey_obj = self.pool.get('survey')
568 resp_obj = self.pool.get('survey.response.line')
569 res_ans_obj = self.pool.get('survey.response.answer')
570 que_obj = self.pool.get('survey.question')
571 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
574 if not sur_name_read['response']:
575 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']})
576 surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
578 response_id = int(sur_name_read['response'])
580 if response_id not in surv_all_resp_obj.search(cr, uid, []):
581 response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context.get('survey_id',False)})
582 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
584 #click first time on next button then increemnet on total start suvey
585 if not safe_eval(sur_name_read['store_ans']):
586 his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
587 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id'][0]})
588 survey_id = sur_name_read['survey_id'][0]
589 sur_rec = survey_obj.read(cr, uid, survey_id)
590 survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
591 if context.has_key('cur_id'):
592 if context.has_key('request') and context.get('request',False):
593 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
594 self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
596 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
597 if sur_name_read['store_ans'] and type(sur_name_read['store_ans']) == dict:
598 for key,val in sur_name_read['store_ans'].items():
600 if field.split('_')[0] == val['question_id']:
602 click_update.append(key)
605 sur_name_read['store_ans'] = {}
609 for key, val in vals.items():
610 que_id = key.split('_')[0]
611 if que_id not in que_li:
612 que_li.append(que_id)
613 que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
615 'question_id': que_id,
616 'date_create': datetime.datetime.now(),
618 'response_id': response_id
620 resp_id = resp_obj.create(cr, uid, res_data)
621 resp_id_list.append(resp_id)
622 sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
623 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
628 comment_field = False
629 comment_value = False
632 for key1, val1 in vals.items():
633 if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
634 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
635 sur_name_read['store_ans'][resp_id].update({key1:val1})
638 elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
640 sur_name_read['store_ans'][resp_id].update({key1:val1})
642 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
645 elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
646 if len(key1.split('_')) > 2:
647 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
648 selected_value.append(val1)
649 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
651 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
652 sur_name_read['store_ans'][resp_id].update({key1:val1})
655 elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
660 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
661 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']:
663 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
666 if que_rec['comment_valid_type'] == 'must_be_whole_number':
668 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
670 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
672 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
674 elif que_rec['comment_valid_type'] == 'must_be_date':
675 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
676 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"):
680 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
682 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
685 for res in resp_id_list:
686 sur_name_read['store_ans'].pop(res)
687 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
689 resp_obj.write(cr, uid, resp_id, {'comment':val1})
690 sur_name_read['store_ans'][resp_id].update({key1:val1})
692 elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
693 resp_obj.write(cr, uid, resp_id, {'comment':val1})
694 sur_name_read['store_ans'][resp_id].update({key1:val1})
697 elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
699 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
700 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']:
702 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
705 if que_rec['validation_type'] == 'must_be_whole_number':
707 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
709 elif que_rec['validation_type'] == 'must_be_decimal_number':
711 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
713 elif que_rec['validation_type'] == 'must_be_date':
714 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
715 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"):
719 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
721 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
724 for res in resp_id_list:
725 sur_name_read['store_ans'].pop(res)
726 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
728 if key1.split('_')[1] == "single" :
729 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
731 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
733 sur_name_read['store_ans'][resp_id].update({key1:val1})
736 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
739 numeric_sum += int(val1)
740 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
741 sur_name_read['store_ans'][resp_id].update({key1:val1})
744 for res in resp_id_list:
745 sur_name_read['store_ans'].pop(res)
746 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + _("Please enter an integer value."))
748 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
749 if type(val1) == type('') or type(val1) == type(u''):
750 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})
751 sur_name_read['store_ans'][resp_id].update({key1:val1})
753 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
754 sur_name_read['store_ans'][resp_id].update({key1:True})
756 matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
759 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
760 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
761 sur_name_read['store_ans'][resp_id].update({key1:val1})
763 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
765 for key,val in vals.items():
766 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
767 for res_id in response_list:
768 if key.split('_')[2] in res_id.split('_')[1]:
769 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
770 sur_name_read['store_ans'][resp_id].update({key:val})
772 if comment_field and comment_value:
773 for res in resp_id_list:
774 sur_name_read['store_ans'].pop(res)
775 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
777 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
778 for res in resp_id_list:
779 sur_name_read['store_ans'].pop(res)
780 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("You cannot select the same answer more than one time."))
783 resp_obj.write(cr, uid, resp_id, {'state':'skip'})
785 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
786 for res in resp_id_list:
787 sur_name_read['store_ans'].pop(res)
788 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
790 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']:
792 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
793 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
794 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
795 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
796 (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'])):
797 for res in resp_id_list:
798 sur_name_read['store_ans'].pop(res)
799 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
801 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
802 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
803 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
804 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
805 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
806 for res in resp_id_list:
807 sur_name_read['store_ans'].pop(res)
808 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
810 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
811 for res in resp_id_list:
812 sur_name_read['store_ans'].pop(res)
813 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
817 for update in click_update:
818 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
819 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
820 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
821 resp_id_list.append(update)
822 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
823 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
828 comment_field = False
829 comment_value = False
832 for key, val in vals.items():
833 ans_id_len = key.split('_')
834 if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
835 if val and key.split('_')[1] == "table":
836 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
837 sur_name_read['store_ans'][update].update({key:val})
838 resp_obj.write(cr, uid, update, {'state': 'done'})
840 elif val and key.split('_')[1] == "otherfield" :
842 sur_name_read['store_ans'][update].update({key:val})
844 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
847 elif val and key.split('_')[1] == "selection":
848 if len(key.split('_')) > 2:
849 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
850 selected_value.append(val)
851 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
853 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
854 resp_obj.write(cr, uid, update, {'state': 'done'})
855 sur_name_read['store_ans'][update].update({key:val})
858 elif key.split('_')[1] == "other":
863 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
864 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']:
866 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
868 if que_rec['comment_valid_type'] == 'must_be_whole_number':
870 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
872 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
874 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
876 elif que_rec['comment_valid_type'] == 'must_be_date':
877 value = datetime.datetime.strptime(val, "%Y-%m-%d")
878 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"):
882 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
884 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
887 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
888 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
889 sur_name_read['store_ans'][update].update({key:val})
891 elif val and key.split('_')[1] == "comment":
892 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
893 sur_name_read['store_ans'][update].update({key:val})
896 elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
898 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
899 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']:
901 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
904 if que_rec['validation_type'] == 'must_be_whole_number':
906 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
908 elif que_rec['validation_type'] == 'must_be_decimal_number':
910 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
912 elif que_rec['validation_type'] == 'must_be_date':
913 value = datetime.datetime.strptime(val, "%Y-%m-%d")
914 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"):
918 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
920 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
923 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
924 if key.split('_')[1] == "single" :
925 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
927 resp_obj.write(cr, uid, update, {'state': 'done'})
928 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
929 sur_name_read['store_ans'][update].update({key:val})
932 elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
935 numeric_sum += int(val)
936 resp_obj.write(cr, uid, update, {'state': 'done'})
937 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
938 sur_name_read['store_ans'][update].update({key:val})
941 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("Please enter an integer value."))
943 elif val and len(key.split('_')) == 3:
944 resp_obj.write(cr, uid, update, {'state': 'done'})
945 if type(val) == type('') or type(val) == type(u''):
946 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})
947 sur_name_read['store_ans'][update].update({key:val})
949 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
950 sur_name_read['store_ans'][update].update({key:True})
951 matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
954 elif val and len(key.split('_')) == 2:
955 resp_obj.write(cr, uid, update, {'state': 'done'})
956 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
957 sur_name_read['store_ans'][update].update({key:val})
959 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
961 for key,val in vals.items():
962 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
963 for res_id in response_list:
964 if key.split('_')[2] in res_id.split('_')[1]:
965 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
966 sur_name_read['store_ans'][update].update({key:val})
968 if comment_field and comment_value:
969 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
971 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
972 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "\n" + _("You cannot select same answer more than one time.'"))
974 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
975 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
978 resp_obj.write(cr, uid, update, {'state': 'skip'})
980 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']:
982 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
983 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
984 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
985 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
986 (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'])):
987 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
989 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
990 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
991 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
992 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
993 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
994 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
996 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
997 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
999 return survey_question_wiz_id
1001 def action_new_question(self,cr, uid, ids, context=None):
1003 New survey.Question form.
1007 for key,val in context.items():
1008 if type(key) == type(True):
1010 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1011 ('name','=','survey_question_wizard_test')])
1013 'view_type': 'form',
1014 "view_mode": 'form',
1015 'res_model': 'survey.question',
1016 'type': 'ir.actions.act_window',
1022 def action_new_page(self, cr, uid, ids, context=None):
1024 New survey.Page form.
1028 for key,val in context.items():
1029 if type(key) == type(True):
1031 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1032 ('name','=','survey_page_wizard_test')])
1034 'view_type': 'form',
1035 "view_mode": 'form',
1036 'res_model': 'survey.page',
1037 'type': 'ir.actions.act_window',
1043 def action_edit_page(self,cr, uid, ids, context=None):
1049 for key,val in context.items():
1050 if type(key) == type(True):
1052 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1053 ('name','=','survey_page_wizard_test')])
1055 'view_type': 'form',
1056 "view_mode": 'form',
1057 'res_model': 'survey.page',
1058 'type': 'ir.actions.act_window',
1060 'res_id': int(context.get('page_id',0)),
1065 def action_delete_page(self,cr, uid, ids, context=None):
1071 for key,val in context.items():
1072 if type(key) == type(True):
1075 self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
1076 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1077 ('name','=','Survey Search')])
1078 surv_name_wiz = self.pool.get('survey.name.wiz')
1079 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
1080 {'transfer':True, 'page_no' : context.get('page_number',False) })
1082 'view_type': 'form',
1083 "view_mode": 'form',
1084 'res_model': 'survey.question.wiz',
1085 'type': 'ir.actions.act_window',
1087 'search_view_id':search_id[0],
1091 def action_edit_question(self,cr, uid, ids, context=None):
1093 Edit survey.question.
1097 for key,val in context.items():
1098 if type(key) == type(True):
1100 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1101 ('name','=','survey_question_wizard_test')])
1103 'view_type': 'form',
1104 "view_mode": 'form',
1105 'res_model': 'survey.question',
1106 'type': 'ir.actions.act_window',
1108 'res_id' : int(context.get('question_id',0)),
1113 def action_delete_question(self,cr, uid, ids, context=None):
1115 Delete survey.question.
1119 for key,val in context.items():
1120 if type(key) == type(True):
1123 que_obj = self.pool.get('survey.question')
1124 que_obj.unlink(cr, uid, [context.get('question_id',False)])
1125 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1126 ('name','=','Survey Search')])
1127 surv_name_wiz = self.pool.get('survey.name.wiz')
1128 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)],\
1129 {'transfer':True, 'page_no' : context.get('page_number',0) })
1131 'view_type': 'form',
1132 "view_mode": 'form',
1133 'res_model': 'survey.question.wiz',
1134 'type': 'ir.actions.act_window',
1136 'search_view_id': search_id[0],
1140 def action_forward_previous(self, cr, uid, ids, context=None):
1142 Goes to previous Survey Answer.
1146 search_obj = self.pool.get('ir.ui.view')
1147 surv_name_wiz = self.pool.get('survey.name.wiz')
1148 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1149 ('name','=','Survey Search')])
1150 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1151 context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
1153 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1156 'view_type': 'form',
1157 "view_mode": 'form',
1158 'res_model': 'survey.question.wiz',
1159 'type': 'ir.actions.act_window',
1161 'search_view_id': search_id[0],
1165 def action_forward_next(self, cr, uid, ids, context=None):
1167 Goes to Next Survey Answer.
1171 search_obj = self.pool.get('ir.ui.view')
1172 surv_name_wiz = self.pool.get('survey.name.wiz')
1173 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1174 ('name','=','Survey Search')])
1175 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1176 context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
1178 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1181 'view_type': 'form',
1182 "view_mode": 'form',
1183 'res_model': 'survey.question.wiz',
1184 'type': 'ir.actions.act_window',
1186 'search_view_id': search_id[0],
1190 def action_next(self, cr, uid, ids, context=None):
1196 surv_name_wiz = self.pool.get('survey.name.wiz')
1197 search_obj = self.pool.get('ir.ui.view')
1198 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1199 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
1201 'view_type': 'form',
1202 "view_mode": 'form',
1203 'res_model': 'survey.question.wiz',
1204 'type': 'ir.actions.act_window',
1206 'search_view_id': search_id[0],
1210 def action_previous(self, cr, uid, ids, context=None):
1212 Goes to previous page.
1216 surv_name_wiz = self.pool.get('survey.name.wiz')
1217 search_obj = self.pool.get('ir.ui.view')
1218 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1219 ('name','=','Survey Search')])
1220 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
1222 'view_type': 'form',
1223 "view_mode": 'form',
1224 'res_model': 'survey.question.wiz',
1225 'type': 'ir.actions.act_window',
1227 'search_view_id': search_id[0],
1231 survey_question_wiz()
1233 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: