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 ##############################################################################
24 from lxml import etree
26 from time import strftime
28 from openerp import tools
29 from openerp.modules.module import get_module_resource
30 from openerp.osv import fields, osv
32 from openerp.tools import to_xml
33 from openerp.tools.translate import _
34 from openerp.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:
140 if sur_name_rec.page_no != 0:
141 p_id = p_id[sur_name_rec.page_no - 1]
142 surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
143 {'page_no' : sur_name_rec.page_no - 1})
147 if sur_name_rec.page_no > 1:
150 pag_rec = page_obj.browse(cr, uid, p_id, context=context)
154 title = pag_rec.title
156 question_ids = pag_rec.question_ids
158 title = sur_rec.title
159 xml_form = etree.Element('form', {'string': tools.ustr(title)})
160 if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
161 context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
162 xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
163 etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
164 etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
165 etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
166 etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
171 if context.has_key('response_id') and context.get('response_id', False) \
172 and int(context.get('response_id',0)[0]) > 0:
173 # TODO: l10n, cleanup this code to make it readable. Or template?
174 xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
175 record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
176 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"})
177 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"})
178 if context.get('response_no',0) > 0:
179 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
180 if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
181 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)})
184 fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
185 etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0),'modifiers':'{"invisible":true}'})
188 xml_group_note = etree.SubElement(xml_form, 'group', {'col': '1','colspan': '4'})
189 for que_test in note.split('\n'):
190 etree.SubElement(xml_group_note, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
191 que_ids = question_ids
196 que_rec = que_obj.browse(cr, uid, que.id, context=context)
197 descriptive_text = ""
198 separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
199 if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
203 if context.has_key('active') and context.get('active',False) and \
204 context.has_key('edit'):
205 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
207 xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
208 context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
209 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
210 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
212 etree.SubElement(xml_form, 'newline')
213 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
215 ans_ids = que_rec.answer_choice_ids
216 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
218 if que_rec.type == 'multiple_choice_only_one_ans':
221 selection.append((tools.ustr(ans.id), ans.answer))
222 xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
223 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
224 fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':_('Answer')}
226 elif que_rec.type == 'multiple_choice_multiple_ans':
227 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
229 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
230 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
232 elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
233 if que_rec.comment_column:
239 xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
241 etree.SubElement(xml_group, 'newline')
242 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))})
243 selection = [('','')]
244 for col in que_rec.column_heading_ids:
245 selection.append((str(col.id), col.title))
246 fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
247 if que_rec.comment_column:
248 fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
249 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
251 elif que_rec.type == 'matrix_of_choices_only_multi_ans':
252 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
253 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
254 for col in que_rec.column_heading_ids:
255 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
257 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
258 for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
259 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
260 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
262 elif que_rec.type == 'matrix_of_drop_down_menus':
263 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
264 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
265 for col in que_rec.column_heading_ids:
266 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
268 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
269 for col in que_rec.column_heading_ids:
272 for item in col.menu_choice.split('\n'):
273 if item and not item.strip() == '': selection.append((item ,item))
274 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
275 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
277 elif que_rec.type == 'multiple_textboxes':
278 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
280 if que_rec.is_validation_require:
281 if que_rec.validation_type in ['must_be_whole_number']:
283 elif que_rec.validation_type in ['must_be_decimal_number']:
285 elif que_rec.validation_type in ['must_be_date']:
288 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
290 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
292 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
294 elif que_rec.type == 'numerical_textboxes':
295 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
297 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
298 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
300 elif que_rec.type == 'date':
301 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
303 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
304 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
306 elif que_rec.type == 'date_and_time':
307 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
309 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
310 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
312 elif que_rec.type == 'descriptive_text':
313 if que_rec.descriptive_text:
314 for que_test in que_rec.descriptive_text.split('\n'):
315 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
317 elif que_rec.type == 'single_textbox':
318 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
319 fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
321 elif que_rec.type == 'comment':
322 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
323 fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
325 elif que_rec.type == 'table':
326 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
327 for col in que_rec.column_heading_ids:
328 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
329 for row in range(0,que_rec.no_of_rows):
330 for col in que_rec.column_heading_ids:
331 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
332 fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
334 elif que_rec.type == 'multiple_textboxes_diff_type':
335 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
337 if ans.type == "email" :
338 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
339 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
341 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
342 if ans.type == "char" :
343 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
344 elif ans.type in ['integer','float','date','datetime']:
345 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
349 for item in ans.menu_choice.split('\n'):
350 if item and not item.strip() == '': selection.append((item ,item))
351 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
353 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:
354 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:
355 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
356 fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
357 if que_rec.comment_field_type == 'char':
358 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
359 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
360 elif que_rec.comment_field_type == 'text':
361 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
362 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
364 if que_rec.comment_field_type == 'char':
365 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
366 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
367 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
368 elif que_rec.comment_field_type == 'text':
369 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
370 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
371 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
373 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '8', 'colspan': '1', 'width':"100%"})
376 etree.SubElement(xml_footer, 'label', {'string': ""})
377 etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':_('Previous'),'type':"object"})
378 but_string = _('Next')
379 if int(page_number) + 1 == total_pages:
380 but_string = _('Done')
381 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)):
382 etree.SubElement(xml_footer, 'label', {'string': ""})
383 etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
384 elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
385 etree.SubElement(xml_footer, 'label', {'string': ""})
386 etree.SubElement(xml_footer, 'button', {'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
387 elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
388 etree.SubElement(xml_footer, 'label', {'string': ""})
389 etree.SubElement(xml_footer, 'button', {'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context), 'class':"oe_highlight"})
391 etree.SubElement(xml_footer, 'label', {'string': ""})
392 etree.SubElement(xml_footer, 'button', {'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
393 etree.SubElement(xml_footer, 'label', {'string': _('or')})
394 etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':_('Exit'),'class':"oe_link"})
395 etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
397 root = xml_form.getroottree()
398 result['arch'] = etree.tostring(root)
399 result['fields'] = fields
400 result['context'] = context
402 survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
403 sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
405 # mark the survey request as done; call 'survey_req_done' on its actual model
406 if context.get('active_model') in self.pool:
407 survey_req_obj = self.pool[context.get('active_model')]
408 if hasattr(survey_req_obj, 'survey_req_done'):
409 survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
411 if sur_rec.send_response:
412 survey_data = survey_obj.browse(cr, uid, survey_id)
413 response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
414 report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
416 pdf_filename = get_module_resource('survey', 'report') + survey_data.title + ".pdf"
417 if os.path.exists(pdf_filename):
418 file = open(pdf_filename)
421 line = file.readline()
426 attachments[survey_data.title + ".pdf"] = file_data
428 os.remove(get_module_resource('survey', 'report') + survey_data.title + ".pdf")
429 context.update({'response_id':response_id})
430 user_email = user_obj.browse(cr, uid, uid, context).email
431 resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
433 if user_email and resp_email:
434 user_name = user_obj.browse(cr, uid, uid, context=context).name
435 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."
436 vals = {'state': 'outgoing',
437 'subject': "Survey Answer Of " + user_name,
438 'body_html': '<pre>%s</pre>' % mail,
439 'email_to': [resp_email],
440 'email_from': user_email}
442 vals['attachment_ids'] = [(0,0,{'name': a_name,
443 'datas_fname': a_name,
444 'datas': str(a_content).encode('base64')})
445 for a_name, a_content in attachments.items()]
446 self.pool.get('mail.mail').create(cr, uid, vals, context=context)
448 xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
449 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '6', 'colspan': '4' ,'class': 'oe_survey_title_height'})
451 etree.SubElement(xml_form, 'separator', {'string': 'Survey Completed', 'colspan': "4"})
452 etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
453 etree.SubElement(xml_form, 'newline')
454 etree.SubElement(xml_footer, 'button', {'special':"cancel",'string':"OK",'colspan':"2",'class':'oe_highlight'})
455 root = xml_form.getroottree()
456 result['arch'] = etree.tostring(root)
457 result['fields'] = {}
458 result['context'] = context
461 def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
463 If any user give answer of survey then last create report of this answer and if 'E-mail Notification on Answer' set True in survey then send mail on responsible person of this survey and attach survey answer report in pdf format.
465 if not report_name or not res_ids:
466 return (False, Exception('Report name and Resources ids are required !!!'))
469 result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, context)
470 ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf'
471 fp = open(ret_file_name, 'wb+');
475 # hr.applicant: if survey answered directly in system: attach report to applicant
476 if context.get('active_model') == 'hr.applicant':
477 self.pool.get('hr.applicant').write(cr,uid,[context.get('active_ids')[0]],{'response':context.get('response_id')})
478 result = base64.b64encode(result)
479 file_name = file_name + '.pdf'
480 ir_attachment = self.pool.get('ir.attachment').create(cr, uid,
483 'datas_fname': file_name,
484 'res_model': context.get('active_model'),
485 'res_id': context.get('active_ids')[0]},
489 return (False, str(e))
490 return (True, ret_file_name)
492 def default_get(self, cr, uid, fields_list, context=None):
494 Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
499 for field in fields_list:
500 if field.split('_')[0] == 'progress':
501 tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
502 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
503 value[field] = tot_per
504 response_obj = self.pool.get('survey.response')
505 surv_name_wiz = self.pool.get('survey.name.wiz')
506 if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
507 data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
508 response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
511 for que in response_ans.question_ids:
512 for field in fields_list:
513 if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
514 if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
515 for ans in que.response_answer_ids:
516 if str(field.split('_')[2]) == str(ans.answer_id.id):
517 value[field] = ans.comment_field
519 if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
520 for ans in que.response_table_ids:
521 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name):
522 value[field] = ans.value
524 if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
525 value[field] = tools.ustr(que.comment)
527 elif que.single_text and field.split('_')[1] == "single":
528 value[field] = tools.ustr(que.single_text)
530 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
531 for ans in que.response_answer_ids:
532 if str(field.split('_')[2]) == str( ans.answer_id.id):
533 value[field] = str(ans.column_id.id)
535 elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
536 value[field] = str(que.response_answer_ids[0].answer_id.id)
538 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
539 for ans in que.response_answer_ids:
540 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
542 value[field] = ans.value_choice
547 for ans in que.response_answer_ids:
548 if str(field.split('_')[1]) == str( ans.answer_id.id):
549 value[field] = ans.answer
553 if not context.has_key('sur_name_id'):
555 if context.has_key('active') and context.get('active',False):
557 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
560 for key,val in safe_eval(sur_name_read.get('store_ans',"{}")).items():
561 for field in fields_list:
562 if field in list(val):
563 value[field] = val[field]
566 def create(self, cr, uid, vals, context=None):
568 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.
570 if context is None: context = {}
572 survey_question_wiz_id = super(survey_question_wiz,self).create(cr, uid, {'name': vals.get('name')}, context=context)
573 if context.has_key('active') and context.get('active',False):
574 return survey_question_wiz_id
576 for key,val in vals.items():
577 if key.split('_')[0] == "progress":
579 if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
580 context.update({'sur_name_id': int(key.split('_')[1])})
585 surv_name_wiz = self.pool.get('survey.name.wiz')
586 surv_all_resp_obj = self.pool.get('survey.response')
587 surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
588 survey_obj = self.pool.get('survey')
589 resp_obj = self.pool.get('survey.response.line')
590 res_ans_obj = self.pool.get('survey.response.answer')
591 que_obj = self.pool.get('survey.question')
592 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
595 if not sur_name_read['response']:
596 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']})
597 surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
599 response_id = int(sur_name_read['response'])
601 if response_id not in surv_all_resp_obj.search(cr, uid, []):
602 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)})
603 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
605 #click first time on next button then increemnet on total start suvey
606 if not safe_eval(sur_name_read['store_ans']):
607 his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
608 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id'][0]})
609 survey_id = sur_name_read['survey_id'][0]
610 sur_rec = survey_obj.read(cr, uid, survey_id)
611 survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
612 if context.has_key('cur_id'):
613 if context.has_key('request') and context.get('request',False):
614 self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
615 self.pool[context.get('object')].survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
617 self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
618 if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict:
619 sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans'])
620 for key,val in sur_name_read['store_ans'].items():
622 if field.split('_')[0] == val['question_id']:
624 click_update.append(key)
627 sur_name_read['store_ans'] = {}
631 for key, val in vals.items():
632 que_id = key.split('_')[0]
633 if que_id not in que_li:
634 que_li.append(que_id)
635 que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
637 'question_id': que_id,
638 'date_create': datetime.datetime.now(),
640 'response_id': response_id
642 resp_id = resp_obj.create(cr, uid, res_data)
643 resp_id_list.append(resp_id)
644 sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
645 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
650 comment_field = False
651 comment_value = False
654 for key1, val1 in vals.items():
655 if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
656 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
657 sur_name_read['store_ans'][resp_id].update({key1:val1})
660 elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
662 sur_name_read['store_ans'][resp_id].update({key1:val1})
664 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
667 elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
668 if len(key1.split('_')) > 2:
669 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
670 selected_value.append(val1)
671 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
673 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
674 sur_name_read['store_ans'][resp_id].update({key1:val1})
677 elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
682 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
683 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']:
685 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
688 if que_rec['comment_valid_type'] == 'must_be_whole_number':
690 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
692 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
694 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
696 elif que_rec['comment_valid_type'] == 'must_be_date':
697 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
698 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"):
702 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
704 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
707 for res in resp_id_list:
708 sur_name_read['store_ans'].pop(res)
709 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
711 resp_obj.write(cr, uid, resp_id, {'comment':val1})
712 sur_name_read['store_ans'][resp_id].update({key1:val1})
714 elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
715 resp_obj.write(cr, uid, resp_id, {'comment':val1})
716 sur_name_read['store_ans'][resp_id].update({key1:val1})
719 elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
721 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
722 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']:
724 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
727 if que_rec['validation_type'] == 'must_be_whole_number':
729 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
731 elif que_rec['validation_type'] == 'must_be_decimal_number':
733 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
735 elif que_rec['validation_type'] == 'must_be_date':
736 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
737 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"):
741 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
743 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
746 for res in resp_id_list:
747 sur_name_read['store_ans'].pop(res)
748 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
750 if key1.split('_')[1] == "single" :
751 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
753 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
755 sur_name_read['store_ans'][resp_id].update({key1:val1})
758 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
761 numeric_sum += int(val1)
762 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
763 sur_name_read['store_ans'][resp_id].update({key1:val1})
766 for res in resp_id_list:
767 sur_name_read['store_ans'].pop(res)
768 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + _("Please enter an integer value."))
770 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
771 if type(val1) == type('') or type(val1) == type(u''):
772 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})
773 sur_name_read['store_ans'][resp_id].update({key1:val1})
775 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
776 sur_name_read['store_ans'][resp_id].update({key1:True})
778 matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
781 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
782 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
783 sur_name_read['store_ans'][resp_id].update({key1:val1})
785 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
787 for key,val in vals.items():
788 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
789 for res_id in response_list:
790 if key.split('_')[2] in res_id.split('_')[1]:
791 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
792 sur_name_read['store_ans'][resp_id].update({key:val})
794 if comment_field and comment_value:
795 for res in resp_id_list:
796 sur_name_read['store_ans'].pop(res)
797 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
799 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
800 for res in resp_id_list:
801 sur_name_read['store_ans'].pop(res)
802 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("You cannot select the same answer more than one time."))
805 resp_obj.write(cr, uid, resp_id, {'state':'skip'})
807 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
808 for res in resp_id_list:
809 sur_name_read['store_ans'].pop(res)
810 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
812 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']:
814 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
815 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
816 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
817 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
818 (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'])):
819 for res in resp_id_list:
820 sur_name_read['store_ans'].pop(res)
821 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
823 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
824 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
825 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
826 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
827 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
828 for res in resp_id_list:
829 sur_name_read['store_ans'].pop(res)
830 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
832 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
833 for res in resp_id_list:
834 sur_name_read['store_ans'].pop(res)
835 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
839 for update in click_update:
840 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
841 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
842 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
843 resp_id_list.append(update)
844 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
845 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
850 comment_field = False
851 comment_value = False
854 for key, val in vals.items():
855 ans_id_len = key.split('_')
856 if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
857 if val and key.split('_')[1] == "table":
858 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
859 sur_name_read['store_ans'][update].update({key:val})
860 resp_obj.write(cr, uid, update, {'state': 'done'})
862 elif val and key.split('_')[1] == "otherfield" :
864 sur_name_read['store_ans'][update].update({key:val})
866 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
869 elif val and key.split('_')[1] == "selection":
870 if len(key.split('_')) > 2:
871 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
872 selected_value.append(val)
873 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
875 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
876 resp_obj.write(cr, uid, update, {'state': 'done'})
877 sur_name_read['store_ans'][update].update({key:val})
880 elif key.split('_')[1] == "other":
885 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
886 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']:
888 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
890 if que_rec['comment_valid_type'] == 'must_be_whole_number':
892 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
894 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
896 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
898 elif que_rec['comment_valid_type'] == 'must_be_date':
899 value = datetime.datetime.strptime(val, "%Y-%m-%d")
900 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"):
904 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
906 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
909 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
910 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
911 sur_name_read['store_ans'][update].update({key:val})
913 elif val and key.split('_')[1] == "comment":
914 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
915 sur_name_read['store_ans'][update].update({key:val})
918 elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
920 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
921 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']:
923 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
926 if que_rec['validation_type'] == 'must_be_whole_number':
928 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
930 elif que_rec['validation_type'] == 'must_be_decimal_number':
932 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
934 elif que_rec['validation_type'] == 'must_be_date':
935 value = datetime.datetime.strptime(val, "%Y-%m-%d")
936 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"):
940 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
942 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
945 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
946 if key.split('_')[1] == "single" :
947 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
949 resp_obj.write(cr, uid, update, {'state': 'done'})
950 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
951 sur_name_read['store_ans'][update].update({key:val})
954 elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
957 numeric_sum += int(val)
958 resp_obj.write(cr, uid, update, {'state': 'done'})
959 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
960 sur_name_read['store_ans'][update].update({key:val})
963 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("Please enter an integer value."))
965 elif val and len(key.split('_')) == 3:
966 resp_obj.write(cr, uid, update, {'state': 'done'})
967 if type(val) == type('') or type(val) == type(u''):
968 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})
969 sur_name_read['store_ans'][update].update({key:val})
971 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
972 sur_name_read['store_ans'][update].update({key:True})
973 matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
976 elif val and len(key.split('_')) == 2:
977 resp_obj.write(cr, uid, update, {'state': 'done'})
978 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
979 sur_name_read['store_ans'][update].update({key:val})
981 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
983 for key,val in vals.items():
984 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
985 for res_id in response_list:
986 if key.split('_')[2] in res_id.split('_')[1]:
987 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
988 sur_name_read['store_ans'][update].update({key:val})
990 if comment_field and comment_value:
991 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
993 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
994 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "\n" + _("You cannot select same answer more than one time.'"))
996 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
997 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
1000 resp_obj.write(cr, uid, update, {'state': 'skip'})
1002 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']:
1004 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
1005 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
1006 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
1007 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
1008 (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'])):
1009 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1011 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
1012 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
1013 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1014 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1015 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1016 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1018 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
1019 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1021 return survey_question_wiz_id
1023 def action_new_question(self, cr, uid, ids, context=None):
1025 New survey.Question form.
1029 for key,val in context.items():
1030 if type(key) == type(True):
1032 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1033 ('name','=','survey_question_wizard_test')])
1035 'view_type': 'form',
1036 "view_mode": 'form',
1037 'res_model': 'survey.question',
1038 'type': 'ir.actions.act_window',
1041 'page_id': int(context.get('page_id',0)),
1045 def action_new_page(self, cr, uid, ids, context=None):
1047 New survey.Page form.
1051 for key,val in context.items():
1052 if type(key) == type(True):
1054 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1055 ('name','=','survey_page_wizard_test')])
1057 'view_type': 'form',
1058 "view_mode": 'form',
1059 'res_model': 'survey.page',
1060 'type': 'ir.actions.act_window',
1066 def action_edit_page(self, cr, uid, ids, context=None):
1072 for key,val in context.items():
1073 if type(key) == type(True):
1075 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1076 ('name','=','survey_page_wizard_test')])
1078 'view_type': 'form',
1079 "view_mode": 'form',
1080 'res_model': 'survey.page',
1081 'type': 'ir.actions.act_window',
1083 'res_id': int(context.get('page_id',0)),
1088 def action_delete_page(self, cr, uid, ids, context=None):
1094 for key,val in context.items():
1095 if type(key) == type(True):
1098 self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
1099 for survey in self.pool.get('survey').browse(cr, uid, [context.get('survey_id',False)], context=context):
1100 if not survey.page_ids:
1101 return {'type':'ir.actions.act_window_close'}
1103 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1104 ('name','=','Survey Search')])
1105 surv_name_wiz = self.pool.get('survey.name.wiz')
1106 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
1107 {'transfer':True, 'page_no' : context.get('page_number',False) })
1109 'view_type': 'form',
1110 "view_mode": 'form',
1111 'res_model': 'survey.question.wiz',
1112 'type': 'ir.actions.act_window',
1114 'search_view_id':search_id[0],
1118 def action_edit_question(self, cr, uid, ids, context=None):
1120 Edit survey.question.
1124 for key,val in context.items():
1125 if type(key) == type(True):
1127 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1128 ('name','=','survey_question_wizard_test')])
1130 'view_type': 'form',
1131 "view_mode": 'form',
1132 'res_model': 'survey.question',
1133 'type': 'ir.actions.act_window',
1135 'res_id' : int(context.get('question_id',0)),
1140 def action_delete_question(self, cr, uid, ids, context=None):
1142 Delete survey.question.
1146 for key,val in context.items():
1147 if type(key) == type(True):
1150 que_obj = self.pool.get('survey.question')
1151 que_obj.unlink(cr, uid, [context.get('question_id',False)])
1152 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1153 ('name','=','Survey Search')])
1154 surv_name_wiz = self.pool.get('survey.name.wiz')
1155 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)],\
1156 {'transfer':True, 'page_no' : context.get('page_number',0) })
1158 'view_type': 'form',
1159 "view_mode": 'form',
1160 'res_model': 'survey.question.wiz',
1161 'type': 'ir.actions.act_window',
1163 'search_view_id': search_id[0],
1167 def action_forward_previous(self, cr, uid, ids, context=None):
1169 Goes to previous Survey Answer.
1173 search_obj = self.pool.get('ir.ui.view')
1174 surv_name_wiz = self.pool.get('survey.name.wiz')
1175 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1176 ('name','=','Survey Search')])
1177 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1178 context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
1180 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1183 'view_type': 'form',
1184 "view_mode": 'form',
1185 'res_model': 'survey.question.wiz',
1186 'type': 'ir.actions.act_window',
1188 'search_view_id': search_id[0],
1192 def action_forward_next(self, cr, uid, ids, context=None):
1194 Goes to Next Survey Answer.
1198 search_obj = self.pool.get('ir.ui.view')
1199 surv_name_wiz = self.pool.get('survey.name.wiz')
1200 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1201 ('name','=','Survey Search')])
1202 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1203 context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
1205 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1208 'view_type': 'form',
1209 "view_mode": 'form',
1210 'res_model': 'survey.question.wiz',
1211 'type': 'ir.actions.act_window',
1213 'search_view_id': search_id[0],
1217 def action_next(self, cr, uid, ids, context=None):
1223 surv_name_wiz = self.pool.get('survey.name.wiz')
1224 search_obj = self.pool.get('ir.ui.view')
1225 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1226 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
1228 'view_type': 'form',
1229 "view_mode": 'form',
1230 'res_model': 'survey.question.wiz',
1231 'type': 'ir.actions.act_window',
1233 'search_view_id': search_id[0],
1237 def action_previous(self, cr, uid, ids, context=None):
1239 Goes to previous page.
1243 surv_name_wiz = self.pool.get('survey.name.wiz')
1244 search_obj = self.pool.get('ir.ui.view')
1245 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1246 ('name','=','Survey Search')])
1247 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
1249 'view_type': 'form',
1250 "view_mode": 'form',
1251 'res_model': 'survey.question.wiz',
1252 'type': 'ir.actions.act_window',
1254 'search_view_id': search_id[0],
1259 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: