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 vals = {'state': 'outgoing',
424 'subject': "Survey Answer Of " + user_name,
425 'body_html': '<pre>%s</pre>' % mail,
426 'email_to': [resp_email],
427 'email_from': user_email}
429 vals['attachment_ids'] = [(0,0,{'name': a_name,
430 'datas_fname': a_name,
431 'datas': str(a_content).encode('base64')})
432 for a_name, a_content in attachments]
433 self.pool.get('mail.mail').create(cr, uid, vals, context=context)
435 xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
436 etree.SubElement(xml_form, 'separator', {'string': 'Complete Survey', 'colspan': "4"})
437 etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
438 etree.SubElement(xml_form, 'newline')
439 etree.SubElement(xml_form, 'button', {'icon': "gtk-go-forward", 'special':"cancel",'string':"OK",'colspan':"2"})
440 root = xml_form.getroottree()
441 result['arch'] = etree.tostring(root)
442 result['fields'] = {}
443 result['context'] = context
446 def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
448 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.
450 if not report_name or not res_ids:
451 return (False, Exception('Report name and Resources ids are required !!!'))
454 service = netsvc.LocalService(report_name);
455 (result, format) = service.create(cr, uid, res_ids, {}, context)
456 ret_file_name = addons.get_module_resource('survey', 'report') + file_name + '.pdf'
457 fp = open(ret_file_name, 'wb+');
461 # hr.applicant: if survey answered directly in system: attach report to applicant
462 if context.get('active_model') == 'hr.applicant':
463 self.pool.get('hr.applicant').write(cr,uid,[context.get('active_ids')[0]],{'response':context.get('response_id')})
464 result = base64.b64encode(result)
465 file_name = file_name + '.pdf'
466 ir_attachment = self.pool.get('ir.attachment').create(cr, uid,
469 'datas_fname': file_name,
470 'res_model': context.get('active_model'),
471 'res_id': context.get('active_ids')[0]},
475 return (False, str(e))
477 return (True, ret_file_name)
479 def default_get(self, cr, uid, fields_list, context=None):
481 Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
486 for field in fields_list:
487 if field.split('_')[0] == 'progress':
488 tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
489 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
490 value[field] = tot_per
491 response_obj = self.pool.get('survey.response')
492 surv_name_wiz = self.pool.get('survey.name.wiz')
494 if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
495 data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
496 response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
499 for que in response_ans.question_ids:
500 for field in fields_list:
501 if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
502 if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
503 for ans in que.response_answer_ids:
504 if str(field.split('_')[2]) == str(ans.answer_id.id):
505 value[field] = ans.comment_field
507 if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
508 for ans in que.response_table_ids:
509 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name):
510 value[field] = ans.value
512 if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
513 value[field] = str(que.comment)
515 elif que.single_text and field.split('_')[1] == "single":
516 value[field] = str(que.single_text)
518 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
519 for ans in que.response_answer_ids:
520 if str(field.split('_')[2]) == str( ans.answer_id.id):
521 value[field] = str(ans.column_id.id)
523 elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
524 value[field] = str(que.response_answer_ids[0].answer_id.id)
526 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
527 for ans in que.response_answer_ids:
528 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
530 value[field] = ans.value_choice
535 for ans in que.response_answer_ids:
536 if str(field.split('_')[1]) == str( ans.answer_id.id):
537 value[field] = ans.answer
540 if not context.has_key('sur_name_id'):
542 if context.has_key('active') and context.get('active',False):
545 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
548 for key,val in safe_eval(sur_name_read.get('store_ans',"{}")).items():
549 for field in fields_list:
550 if field in list(val):
551 value[field] = val[field]
555 def create(self, cr, uid, vals, context=None):
557 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.
559 if context is None: context = {}
561 survey_question_wiz_id = super(survey_question_wiz,self).create(cr, uid, {'name': vals.get('name')}, context=context)
562 if context.has_key('active') and context.get('active',False):
563 return survey_question_wiz_id
565 for key,val in vals.items():
566 if key.split('_')[0] == "progress":
568 if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
569 context.update({'sur_name_id': int(key.split('_')[1])})
574 surv_name_wiz = self.pool.get('survey.name.wiz')
575 surv_all_resp_obj = self.pool.get('survey.response')
576 surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
577 survey_obj = self.pool.get('survey')
578 resp_obj = self.pool.get('survey.response.line')
579 res_ans_obj = self.pool.get('survey.response.answer')
580 que_obj = self.pool.get('survey.question')
581 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
584 if not sur_name_read['response']:
585 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']})
586 surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
588 response_id = int(sur_name_read['response'])
590 if response_id not in surv_all_resp_obj.search(cr, uid, []):
591 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)})
592 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
594 #click first time on next button then increemnet on total start suvey
595 if not safe_eval(sur_name_read['store_ans']):
596 his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
597 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id'][0]})
598 survey_id = sur_name_read['survey_id'][0]
599 sur_rec = survey_obj.read(cr, uid, survey_id)
600 survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
601 if context.has_key('cur_id'):
602 if context.has_key('request') and context.get('request',False):
603 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
604 self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
606 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
607 if sur_name_read['store_ans'] and type(sur_name_read['store_ans']) == dict:
608 for key,val in sur_name_read['store_ans'].items():
610 if field.split('_')[0] == val['question_id']:
612 click_update.append(key)
615 sur_name_read['store_ans'] = {}
619 for key, val in vals.items():
620 que_id = key.split('_')[0]
621 if que_id not in que_li:
622 que_li.append(que_id)
623 que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
625 'question_id': que_id,
626 'date_create': datetime.datetime.now(),
628 'response_id': response_id
630 resp_id = resp_obj.create(cr, uid, res_data)
631 resp_id_list.append(resp_id)
632 sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
633 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
638 comment_field = False
639 comment_value = False
642 for key1, val1 in vals.items():
643 if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
644 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
645 sur_name_read['store_ans'][resp_id].update({key1:val1})
648 elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
650 sur_name_read['store_ans'][resp_id].update({key1:val1})
652 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
655 elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
656 if len(key1.split('_')) > 2:
657 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
658 selected_value.append(val1)
659 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
661 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
662 sur_name_read['store_ans'][resp_id].update({key1:val1})
665 elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
670 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
671 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']:
673 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
676 if que_rec['comment_valid_type'] == 'must_be_whole_number':
678 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
680 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
682 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
684 elif que_rec['comment_valid_type'] == 'must_be_date':
685 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
686 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"):
690 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
692 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
695 for res in resp_id_list:
696 sur_name_read['store_ans'].pop(res)
697 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
699 resp_obj.write(cr, uid, resp_id, {'comment':val1})
700 sur_name_read['store_ans'][resp_id].update({key1:val1})
702 elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
703 resp_obj.write(cr, uid, resp_id, {'comment':val1})
704 sur_name_read['store_ans'][resp_id].update({key1:val1})
707 elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
709 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
710 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']:
712 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
715 if que_rec['validation_type'] == 'must_be_whole_number':
717 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
719 elif que_rec['validation_type'] == 'must_be_decimal_number':
721 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
723 elif que_rec['validation_type'] == 'must_be_date':
724 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
725 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"):
729 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
731 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
734 for res in resp_id_list:
735 sur_name_read['store_ans'].pop(res)
736 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
738 if key1.split('_')[1] == "single" :
739 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
741 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
743 sur_name_read['store_ans'][resp_id].update({key1:val1})
746 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
749 numeric_sum += int(val1)
750 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
751 sur_name_read['store_ans'][resp_id].update({key1:val1})
754 for res in resp_id_list:
755 sur_name_read['store_ans'].pop(res)
756 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + _("Please enter an integer value."))
758 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
759 if type(val1) == type('') or type(val1) == type(u''):
760 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})
761 sur_name_read['store_ans'][resp_id].update({key1:val1})
763 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
764 sur_name_read['store_ans'][resp_id].update({key1:True})
766 matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
769 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
770 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
771 sur_name_read['store_ans'][resp_id].update({key1:val1})
773 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
775 for key,val in vals.items():
776 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
777 for res_id in response_list:
778 if key.split('_')[2] in res_id.split('_')[1]:
779 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
780 sur_name_read['store_ans'][resp_id].update({key:val})
782 if comment_field and comment_value:
783 for res in resp_id_list:
784 sur_name_read['store_ans'].pop(res)
785 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
787 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
788 for res in resp_id_list:
789 sur_name_read['store_ans'].pop(res)
790 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("You cannot select the same answer more than one time."))
793 resp_obj.write(cr, uid, resp_id, {'state':'skip'})
795 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
796 for res in resp_id_list:
797 sur_name_read['store_ans'].pop(res)
798 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
800 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']:
802 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
803 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
804 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
805 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
806 (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'])):
807 for res in resp_id_list:
808 sur_name_read['store_ans'].pop(res)
809 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
811 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
812 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
813 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
814 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
815 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
816 for res in resp_id_list:
817 sur_name_read['store_ans'].pop(res)
818 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
820 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
821 for res in resp_id_list:
822 sur_name_read['store_ans'].pop(res)
823 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
827 for update in click_update:
828 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
829 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
830 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
831 resp_id_list.append(update)
832 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
833 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
838 comment_field = False
839 comment_value = False
842 for key, val in vals.items():
843 ans_id_len = key.split('_')
844 if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
845 if val and key.split('_')[1] == "table":
846 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
847 sur_name_read['store_ans'][update].update({key:val})
848 resp_obj.write(cr, uid, update, {'state': 'done'})
850 elif val and key.split('_')[1] == "otherfield" :
852 sur_name_read['store_ans'][update].update({key:val})
854 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
857 elif val and key.split('_')[1] == "selection":
858 if len(key.split('_')) > 2:
859 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
860 selected_value.append(val)
861 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
863 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
864 resp_obj.write(cr, uid, update, {'state': 'done'})
865 sur_name_read['store_ans'][update].update({key:val})
868 elif key.split('_')[1] == "other":
873 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
874 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']:
876 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
878 if que_rec['comment_valid_type'] == 'must_be_whole_number':
880 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
882 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
884 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
886 elif que_rec['comment_valid_type'] == 'must_be_date':
887 value = datetime.datetime.strptime(val, "%Y-%m-%d")
888 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"):
892 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
894 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
897 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
898 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
899 sur_name_read['store_ans'][update].update({key:val})
901 elif val and key.split('_')[1] == "comment":
902 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
903 sur_name_read['store_ans'][update].update({key:val})
906 elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
908 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
909 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']:
911 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
914 if que_rec['validation_type'] == 'must_be_whole_number':
916 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
918 elif que_rec['validation_type'] == 'must_be_decimal_number':
920 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
922 elif que_rec['validation_type'] == 'must_be_date':
923 value = datetime.datetime.strptime(val, "%Y-%m-%d")
924 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"):
928 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
930 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
933 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
934 if key.split('_')[1] == "single" :
935 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
937 resp_obj.write(cr, uid, update, {'state': 'done'})
938 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
939 sur_name_read['store_ans'][update].update({key:val})
942 elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
945 numeric_sum += int(val)
946 resp_obj.write(cr, uid, update, {'state': 'done'})
947 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
948 sur_name_read['store_ans'][update].update({key:val})
951 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("Please enter an integer value."))
953 elif val and len(key.split('_')) == 3:
954 resp_obj.write(cr, uid, update, {'state': 'done'})
955 if type(val) == type('') or type(val) == type(u''):
956 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})
957 sur_name_read['store_ans'][update].update({key:val})
959 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
960 sur_name_read['store_ans'][update].update({key:True})
961 matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
964 elif val and len(key.split('_')) == 2:
965 resp_obj.write(cr, uid, update, {'state': 'done'})
966 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
967 sur_name_read['store_ans'][update].update({key:val})
969 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
971 for key,val in vals.items():
972 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
973 for res_id in response_list:
974 if key.split('_')[2] in res_id.split('_')[1]:
975 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
976 sur_name_read['store_ans'][update].update({key:val})
978 if comment_field and comment_value:
979 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
981 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
982 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "\n" + _("You cannot select same answer more than one time.'"))
984 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
985 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
988 resp_obj.write(cr, uid, update, {'state': 'skip'})
990 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']:
992 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
993 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
994 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
995 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
996 (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'])):
997 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
999 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
1000 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
1001 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1002 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1003 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1004 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1006 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
1007 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1009 return survey_question_wiz_id
1011 def action_new_question(self,cr, uid, ids, context=None):
1013 New survey.Question form.
1017 for key,val in context.items():
1018 if type(key) == type(True):
1020 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1021 ('name','=','survey_question_wizard_test')])
1023 'view_type': 'form',
1024 "view_mode": 'form',
1025 'res_model': 'survey.question',
1026 'type': 'ir.actions.act_window',
1032 def action_new_page(self, cr, uid, ids, context=None):
1034 New survey.Page form.
1038 for key,val in context.items():
1039 if type(key) == type(True):
1041 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1042 ('name','=','survey_page_wizard_test')])
1044 'view_type': 'form',
1045 "view_mode": 'form',
1046 'res_model': 'survey.page',
1047 'type': 'ir.actions.act_window',
1053 def action_edit_page(self,cr, uid, ids, context=None):
1059 for key,val in context.items():
1060 if type(key) == type(True):
1062 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1063 ('name','=','survey_page_wizard_test')])
1065 'view_type': 'form',
1066 "view_mode": 'form',
1067 'res_model': 'survey.page',
1068 'type': 'ir.actions.act_window',
1070 'res_id': int(context.get('page_id',0)),
1075 def action_delete_page(self,cr, uid, ids, context=None):
1081 for key,val in context.items():
1082 if type(key) == type(True):
1085 self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
1086 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1087 ('name','=','Survey Search')])
1088 surv_name_wiz = self.pool.get('survey.name.wiz')
1089 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
1090 {'transfer':True, 'page_no' : context.get('page_number',False) })
1092 'view_type': 'form',
1093 "view_mode": 'form',
1094 'res_model': 'survey.question.wiz',
1095 'type': 'ir.actions.act_window',
1097 'search_view_id':search_id[0],
1101 def action_edit_question(self,cr, uid, ids, context=None):
1103 Edit survey.question.
1107 for key,val in context.items():
1108 if type(key) == type(True):
1110 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1111 ('name','=','survey_question_wizard_test')])
1113 'view_type': 'form',
1114 "view_mode": 'form',
1115 'res_model': 'survey.question',
1116 'type': 'ir.actions.act_window',
1118 'res_id' : int(context.get('question_id',0)),
1123 def action_delete_question(self,cr, uid, ids, context=None):
1125 Delete survey.question.
1129 for key,val in context.items():
1130 if type(key) == type(True):
1133 que_obj = self.pool.get('survey.question')
1134 que_obj.unlink(cr, uid, [context.get('question_id',False)])
1135 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1136 ('name','=','Survey Search')])
1137 surv_name_wiz = self.pool.get('survey.name.wiz')
1138 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)],\
1139 {'transfer':True, 'page_no' : context.get('page_number',0) })
1141 'view_type': 'form',
1142 "view_mode": 'form',
1143 'res_model': 'survey.question.wiz',
1144 'type': 'ir.actions.act_window',
1146 'search_view_id': search_id[0],
1150 def action_forward_previous(self, cr, uid, ids, context=None):
1152 Goes to previous Survey Answer.
1156 search_obj = self.pool.get('ir.ui.view')
1157 surv_name_wiz = self.pool.get('survey.name.wiz')
1158 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1159 ('name','=','Survey Search')])
1160 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1161 context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
1163 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1166 'view_type': 'form',
1167 "view_mode": 'form',
1168 'res_model': 'survey.question.wiz',
1169 'type': 'ir.actions.act_window',
1171 'search_view_id': search_id[0],
1175 def action_forward_next(self, cr, uid, ids, context=None):
1177 Goes to Next Survey Answer.
1181 search_obj = self.pool.get('ir.ui.view')
1182 surv_name_wiz = self.pool.get('survey.name.wiz')
1183 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1184 ('name','=','Survey Search')])
1185 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1186 context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
1188 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1191 'view_type': 'form',
1192 "view_mode": 'form',
1193 'res_model': 'survey.question.wiz',
1194 'type': 'ir.actions.act_window',
1196 'search_view_id': search_id[0],
1200 def action_next(self, cr, uid, ids, context=None):
1206 surv_name_wiz = self.pool.get('survey.name.wiz')
1207 search_obj = self.pool.get('ir.ui.view')
1208 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1209 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
1211 'view_type': 'form',
1212 "view_mode": 'form',
1213 'res_model': 'survey.question.wiz',
1214 'type': 'ir.actions.act_window',
1216 'search_view_id': search_id[0],
1220 def action_previous(self, cr, uid, ids, context=None):
1222 Goes to previous page.
1226 surv_name_wiz = self.pool.get('survey.name.wiz')
1227 search_obj = self.pool.get('ir.ui.view')
1228 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1229 ('name','=','Survey Search')])
1230 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
1232 'view_type': 'form',
1233 "view_mode": 'form',
1234 'res_model': 'survey.question.wiz',
1235 'type': 'ir.actions.act_window',
1237 'search_view_id': search_id[0],
1241 survey_question_wiz()
1243 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: