survey: fix non-latin in report, f-v-g() of wizard.
[odoo/odoo.git] / addons / survey / wizard / survey_answer.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22 import os
23 import datetime
24 from lxml import etree
25 from time import strftime
26
27 import tools
28 import netsvc
29 from osv import osv
30 from osv import fields
31 from tools import to_xml
32 from tools.translate import _
33
34 class survey_question_wiz(osv.osv_memory):
35     _name = 'survey.question.wiz'
36     _columns = {
37         'name': fields.integer('Number'),
38     }
39
40     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
41         """
42         Fields View Get method :- generate the new view and display the survey pages of selected survey.
43
44         @param self: The object pointer
45         @param cr: the current row, from the database cursor,
46         @param uid: the current user’s ID for security checks,
47         @param view_id : view id of the current object.
48         @param view_type : which type of view is create. like :- form, tree ,search etc...
49         @param context: A standard dictionary for contextual values
50         @return : Dictionary value for created view of particular survey pages.
51         """
52
53         result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
54                                         view_type, context, toolbar,submenu)
55
56         surv_name_wiz = self.pool.get('survey.name.wiz')
57         survey_obj = self.pool.get('survey')
58         page_obj = self.pool.get('survey.page')
59         que_obj = self.pool.get('survey.question')
60         ans_obj = self.pool.get('survey.answer')
61         sur_response_obj = self.pool.get('survey.response')
62         que_col_head = self.pool.get('survey.question.column.heading')
63         user_obj = self.pool.get('res.users')
64
65         if view_type in ['form']:
66             wiz_id = 0
67             if not context.has_key('sur_name_id'):
68                 res_data = {
69                     'survey_id': context.get('survey_id', False),
70                     'page_no': -1,
71                     'page': 'next',
72                     'transfer': 1,
73                     'response': 0
74                 }
75                 wiz_id = surv_name_wiz.create(cr, uid, res_data)
76                 sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id)
77                 context.update({'sur_name_id' :wiz_id})
78             else:
79                 sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'])
80
81             if context.has_key('active_id'):
82                 context.pop('active_id')
83
84             survey_id = context.get('survey_id', False)
85             if not survey_id:
86                 # Try one more time to find it
87                 if sur_name_rec.survey_id:
88                     survey_id = sur_name_rec.survey_id[0]
89                 else:
90                     # raise osv.except_osv(_('Error!'), _("Cannot locate survey for the question wizard!"))
91                     # If this function is called without a survey_id in
92                     # its context, it makes no sense to return any view.
93                     # Just return the default, empty view for this object,
94                     # in order to please random calls to this fn().
95                     return super(survey_question_wiz, self).\
96                                 fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context,
97                                         toolbar=toolbar, submenu=submenu)
98
99             sur_rec = survey_obj.browse(cr, uid, survey_id)
100             p_id = map(lambda x:x.id, sur_rec.page_ids)
101             total_pages = len(p_id)
102             pre_button = False
103             readonly = 0
104
105             if context.get('response_id', False) \
106                             and int(context['response_id'][0]) > 0:
107                 readonly = 1
108
109             if not sur_name_rec.page_no + 1 :
110                 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
111
112             sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'])
113             page_number = int(sur_name_rec.page_no)
114             if sur_name_read.transfer or not sur_name_rec.page_no + 1:
115                 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
116                 flag = False
117                 fields = {}
118                 if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
119                     if total_pages > sur_name_rec.page_no + 1:
120                         if ((context.has_key('active') and not context.get('active', False)) \
121                                     or not context.has_key('active')) and not sur_name_rec.page_no + 1:
122                             if sur_rec.state != "open" :
123                                 raise osv.except_osv(_('Warning !'),_("You can not give answer because of survey is not open for answer"))
124                             cr.execute('select count(id) from survey_history where user_id=%s\
125                                                     and survey_id=%s', (uid,survey_id))
126                             res = cr.fetchone()[0]
127                             user_limit = survey_obj.browse(cr, uid, survey_id)
128                             user_limit = user_limit.response_user
129                             if user_limit and res >= user_limit:
130                                 raise osv.except_osv(_('Warning !'),_("You can not give answer for this survey more than %s times") % (user_limit))
131
132                         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:
133                             survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
134
135                         p_id = p_id[sur_name_rec.page_no + 1]
136                         surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
137                         flag = True
138                         page_number += 1
139                     if sur_name_rec.page_no > - 1:
140                         pre_button = True
141                 else:
142                     if sur_name_rec.page_no != 0:
143                         p_id = p_id[sur_name_rec.page_no - 1]
144                         surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
145                                              {'page_no' : sur_name_rec.page_no - 1})
146                         flag = True
147                         page_number -= 1
148
149                     if sur_name_rec.page_no > 1:
150                         pre_button = True
151                 if flag:
152                     pag_rec = page_obj.browse(cr, uid, p_id)
153                     xml_form = etree.Element('form', {'string': _(tools.ustr(pag_rec.title))})
154                     xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
155                     if context.has_key('response_id') and context.get('response_id', False) \
156                          and int(context.get('response_id',0)[0]) > 0:
157                         # TODO: l10n, cleanup this code to make it readable. Or template?
158                         xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
159                         record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
160                         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"})
161                         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"})
162                         if context.get('response_no',0) > 0:
163                             etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
164                         if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
165                             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)})
166
167                     if wiz_id:
168                         fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
169                         etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0)})
170
171                     if pag_rec.note:
172                         xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
173                         for que_test in pag_rec.note.split('\n'):
174                             etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
175                     que_ids = pag_rec.question_ids
176                     qu_no = 0
177
178                     for que in que_ids:
179                         qu_no += 1
180                         que_rec = que_obj.browse(cr, uid, que.id)
181                         descriptive_text = ""
182                         separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
183                         if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
184                             star = '*'
185                         else:
186                             star = ''
187                         xml_group = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '4'})
188
189                         if context.has_key('active') and context.get('active',False) and \
190                                     context.has_key('edit'):
191                             xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '2'})
192                             etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '3'})
193                             xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
194                             context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
195                             etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
196                             etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
197                         else:
198                             xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
199                             etree.SubElement(xml_group, 'separator', {'string': star+to_xml(separator_string), 'colspan': '4'})
200
201                         ans_ids = que_rec.answer_choice_ids
202                         xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
203
204                         if que_rec.type == 'multiple_choice_only_one_ans':
205                             selection = []
206                             for ans in ans_ids:
207                                 selection.append((tools.ustr(ans.id), ans.answer))
208                             xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
209                             etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
210                             fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"}
211
212                         elif que_rec.type == 'multiple_choice_multiple_ans':
213                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
214                             for ans in ans_ids:
215                                 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
216                                 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
217
218                         elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
219                             if que_rec.comment_column:
220                                 col = "4"
221                                 colspan = "4"
222                             else:
223                                col = "2"
224                                colspan = "2"
225                             xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
226                             for row in ans_ids:
227                                 etree.SubElement(xml_group, 'newline')
228                                 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))})
229                                 selection = [('','')]
230                                 for col in que_rec.column_heading_ids:
231                                     selection.append((str(col.id), col.title))
232                                 fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
233                                 if que_rec.comment_column:
234                                    fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
235                                    etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
236
237                         elif que_rec.type == 'matrix_of_choices_only_multi_ans':
238                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
239                             etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
240                             for col in que_rec.column_heading_ids:
241                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
242                             for row in ans_ids:
243                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
244                                 for col in que_col_head.read(cr, uid, que_rec.column_heading_ids):
245                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
246                                     fields[tools.ustr(que.id) + "_" + tools.ustr(row.id)  + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
247
248                         elif que_rec.type == 'matrix_of_drop_down_menus':
249                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
250                             etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
251                             for col in que_rec.column_heading_ids:
252                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
253                             for row in ans_ids:
254                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
255                                 for col in que_rec.column_heading_ids:
256                                     selection = []
257                                     if col.menu_choice:
258                                         for item in col.menu_choice.split('\n'):
259                                             if item and not item.strip() == '': selection.append((item ,item))
260                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
261                                     fields[tools.ustr(que.id) + "_" + tools.ustr(row.id)  + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
262
263                         elif que_rec.type == 'multiple_textboxes':
264                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
265                             type = "char"
266                             if que_rec.is_validation_require:
267                                 if que_rec.validation_type in ['must_be_whole_number']:
268                                     type = "integer"
269                                 elif que_rec.validation_type in ['must_be_decimal_number']:
270                                     type = "float"
271                                 elif que_rec.validation_type in ['must_be_date']:
272                                     type = "date"
273                             for ans in ans_ids:
274                                 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
275                                 if type == "char" :
276                                     fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
277                                 else:
278                                     fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
279
280                         elif que_rec.type == 'numerical_textboxes':
281                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
282                             for ans in ans_ids:
283                                 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
284                                 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
285
286                         elif que_rec.type == 'date':
287                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
288                             for ans in ans_ids:
289                                 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
290                                 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
291
292                         elif que_rec.type == 'date_and_time':
293                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
294                             for ans in ans_ids:
295                                 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
296                                 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
297
298                         elif que_rec.type == 'descriptive_text':
299                             for que_test in que_rec.descriptive_text.split('\n'):
300                                 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
301
302                         elif que_rec.type == 'single_textbox':
303                             etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
304                             fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
305
306                         elif que_rec.type == 'comment':
307                             etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
308                             fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
309
310                         elif que_rec.type == 'table':
311                             xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
312                             for col in que_rec.column_heading_ids:
313                                 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
314                             for row in range(0,que_rec.no_of_rows):
315                                 for col in que_rec.column_heading_ids:
316                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
317                                     fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
318
319                         elif que_rec.type == 'multiple_textboxes_diff_type':
320                             xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
321                             for ans in ans_ids:
322                                 if ans.type == "email" :
323                                     fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
324                                     etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
325                                 else:
326                                     etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
327                                     if ans.type == "char" :
328                                         fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
329                                     elif ans.type in ['integer','float','date','datetime']:
330                                         fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
331                                     else:
332                                         selection = []
333                                         if ans.menu_choice:
334                                             for item in ans.menu_choice.split('\n'):
335                                                 if item and not item.strip() == '': selection.append((item ,item))
336                                         fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
337
338                         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:
339                             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:
340                                 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
341                                 fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
342                                 if que_rec.comment_field_type == 'char':
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': 'char', 'string': '', 'size':255, 'views':{}}
345                                 elif que_rec.comment_field_type == 'text':
346                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
347                                     fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
348                             else:
349                                 if que_rec.comment_field_type == 'char':
350                                     etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
351                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
352                                     fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
353                                 elif que_rec.comment_field_type == 'text':
354                                     etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
355                                     etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
356                                     fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
357
358                     etree.SubElement(xml_form, 'separator', {'colspan': '4'})
359                     xml_group = etree.SubElement(xml_form, 'group', {'col': '6', 'colspan': '4'})
360                     etree.SubElement(xml_group, 'field', {'name': 'progress_bar_' + tools.ustr(page_number) , 'widget':'progressbar'})
361                     fields['progress_bar_' + tools.ustr(page_number)] = {'type':'float', 'string':"Progress", 'views':{}}
362                     etree.SubElement(xml_group, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages)})
363                     etree.SubElement(xml_group, 'button', {'icon': "gtk-cancel", 'special': "cancel",'string':"Cancel"})
364
365                     if pre_button:
366                         etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_previous",'string':"Previous",'type':"object"})
367                     but_string = "Next"
368                     if int(page_number) + 1 == total_pages:
369                         but_string = "Done"
370
371                     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)):
372                         etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context)})
373                     elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
374                         etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)})
375                     elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
376                         etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context)})
377                     else:
378                         etree.SubElement(xml_group, 'button', {'icon': "gtk-go-forward", 'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context)})
379
380                     if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
381                         etree.SubElement(xml_form, 'separator', {'string' : '','colspan': '4'})
382                         context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
383                         xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
384                         etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
385                         etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
386                         etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
387                         etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
388
389                     root = xml_form.getroottree()
390                     result['arch'] = etree.tostring(root)
391                     result['fields'] = fields
392                     result['context'] = context
393                 else:
394                     survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
395                     sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
396
397                     if sur_rec.send_response:
398                         survey_data = survey_obj.browse(cr, uid, int(survey_id))
399                         response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
400                         context.update({'response_id':response_id})
401                         report = self.create_report(cr, uid, [int(survey_id)], 'report.survey.browse.response', survey_data.title,context)
402                         attachments = []
403                         file = open(tools.config['addons_path'] + '/survey/report/' + survey_data.title + ".pdf")
404                         file_data = ""
405                         while 1:
406                             line = file.readline()
407                             file_data += line
408                             if not line:
409                                 break
410
411                         attachments.append((survey_data.title + ".pdf",file_data))
412                         file.close()
413                         os.remove(tools.config['addons_path'] + '/survey/report/' + survey_data.title + ".pdf")
414                         user_email = False
415                         resp_email = False
416
417                         address_id = user_obj.browse(cr, uid, uid).address_id.id
418                         if address_id:
419                             cr.execute("select email from res_partner_address where id =%s", (address_id,))
420                             user_email = cr.fetchone()[0]
421                         resp_id = survey_data.responsible_id.address_id
422
423                         if resp_id:
424                             cr.execute("select email from res_partner_address where id =%s", (resp_id.id,))
425                             resp_email = cr.fetchone()[0]
426                         if user_email and resp_email:
427                             user_name = user_obj.browse(cr, uid, uid).name
428                             mail = "Hello " + survey_data.responsible_id.name + ",\n\n " + str(user_name) + " Give Response Of " + survey_data.title + " Survey.\n\n Thanks,"
429                             tools.email_send(user_email, [resp_email], "Survey Answer Of " + str(user_name) , mail, attach = attachments)
430
431                     xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
432                     etree.SubElement(xml_form, 'separator', {'string': 'Complete Survey', 'colspan': "4"})
433                     etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
434                     etree.SubElement(xml_form, 'newline')
435                     etree.SubElement(xml_form, 'button', {'icon': "gtk-go-forward", 'special':"cancel",'string':"OK",'colspan':"2"})
436                     root = xml_form.getroottree()
437                     result['arch'] = etree.tostring(root)
438                     result['fields'] = {}
439                     result['context'] = context
440         return result
441
442     def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
443         """
444         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.
445
446         @param self: The object pointer
447         @param cr: the current row, from the database cursor,
448         @param uid: the current user’s ID for security checks,
449         @param res_ids: List of survey answer IDs,
450         @param report_name: name of the report,
451         @param file_name: To give file name of the report,
452         @param context: A standard dictionary for contextual values,
453         @return : Dictionary value for created report with file nameself.
454         """
455         if not report_name or not res_ids:
456             return (False, Exception('Report name and Resources ids are required !!!'))
457         try:
458             ret_file_name = tools.config['addons_path'] + '/survey/report/' + file_name + '.pdf'
459             service = netsvc.LocalService(report_name);
460             (result, format) = service.create(cr, uid, res_ids, {}, context)
461             fp = open(ret_file_name, 'wb+');
462             fp.write(result);
463             fp.close();
464
465         except Exception,e:
466             return (False, str(e))
467
468         return (True, ret_file_name)
469
470     def default_get(self, cr, uid, fields_list, context=None):
471         """
472         Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
473
474         @param self: The object pointer
475         @param cr: the current row, from the database cursor,
476         @param uid: the current user’s ID for security checks,
477         @param fields_list: List of fields of current view,
478         @param context: A standard dictionary for contextual values,
479         @return : Dictionary value for fields list with value.
480         """
481         value = {}
482         for field in fields_list:
483             if field.split('_')[0] == 'progress':
484                 tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
485                 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
486                 value[field] = tot_per
487         response_obj = self.pool.get('survey.response')
488         surv_name_wiz = self.pool.get('survey.name.wiz')
489
490         if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
491             data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
492             response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
493             fields_list.sort()
494
495             for que in response_ans.question_ids:
496                 for field in fields_list:
497                     if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
498                         if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
499                             for ans in que.response_answer_ids:
500                                 if str(field.split('_')[2]) == str(ans.answer_id.id):
501                                     value[field] = ans.comment_field
502
503                         if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
504                             for ans in que.response_table_ids:
505                                 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) ==  str(ans.name):
506                                     value[field] = ans.value
507
508                         if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
509                             value[field] = str(que.comment)
510
511                         elif que.single_text and field.split('_')[1] == "single":
512                             value[field] = str(que.single_text)
513
514                         elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
515                             for ans in que.response_answer_ids:
516                                 if str(field.split('_')[2]) == str( ans.answer_id.id):
517                                     value[field] = str(ans.column_id.id)
518
519                         elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
520                             value[field] = str(que.response_answer_ids[0].answer_id.id)
521
522                         elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
523                             for ans in que.response_answer_ids:
524                                 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
525                                     if ans.value_choice:
526                                         value[field] = ans.value_choice
527                                     else:
528                                         value[field] = True
529
530                         else:
531                             for ans in que.response_answer_ids:
532                                 if str(field.split('_')[1]) == str( ans.answer_id.id):
533                                     value[field] = ans.answer
534
535         else:
536             if not context.has_key('sur_name_id'):
537                 return value
538             if context.has_key('active') and context.get('active',False):
539                 return value
540
541             sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
542             ans_list = []
543             for key,val in sur_name_read['store_ans'].items():
544                 for field in fields_list:
545                     if field in list(val):
546                         value[field] = val[field]
547
548         return value
549
550     def create(self, cr, uid, vals, context=None):
551         """
552         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.
553
554         @param self: The object pointer
555         @param cr: the current row, from the database cursor,
556         @param uid: the current user’s ID for security checks,
557         @param vals: Values,
558         @param context: A standard dictionary for contextual values
559         @return : True.
560         """
561         if context.has_key('active') and context.get('active',False):
562             return True
563
564         for key,val in vals.items():
565             if key.split('_')[0] == "progress":
566                 vals.pop(key)
567             if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
568                 context.update({'sur_name_id': int(key.split('_')[1])})
569                 vals.pop(key)
570
571         click_state = True
572         click_update = []
573         surv_name_wiz = self.pool.get('survey.name.wiz')
574         surv_all_resp_obj = self.pool.get('survey.response')
575         surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
576         survey_obj = self.pool.get('survey')
577         resp_obj = self.pool.get('survey.response.line')
578         res_ans_obj = self.pool.get('survey.response.answer')
579         que_obj = self.pool.get('survey.question')
580         sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
581         response_id =  0
582
583         if not sur_name_read['response']:
584             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']})
585             surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
586         else:
587             response_id = int(sur_name_read['response'])
588
589         if response_id not in surv_all_resp_obj.search(cr, uid, []):
590             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)})
591             surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
592
593         #click first time on next button then increemnet on total start suvey
594         if not sur_name_read['store_ans']:
595             his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
596                                               'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id']})
597             sur_rec = survey_obj.read(cr, uid, sur_name_read['survey_id'])
598             survey_obj.write(cr, uid, sur_name_read['survey_id'],  {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
599             if context.has_key('cur_id'):
600                 if context.has_key('request') and context.get('request',False):
601                     self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
602                     self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
603                 else:
604                     self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
605         if sur_name_read['store_ans'] and type(sur_name_read['store_ans']) == dict:
606             for key,val in sur_name_read['store_ans'].items():
607                 for field in vals:
608                     if field.split('_')[0] == val['question_id']:
609                         click_state = False
610                         click_update.append(key)
611                         break
612         else:
613             sur_name_read['store_ans'] = {}
614         if click_state:
615             que_li = []
616             resp_id_list = []
617             for key, val in vals.items():
618                 que_id = key.split('_')[0]
619                 if que_id not in que_li:
620                     que_li.append(que_id)
621                     que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
622                     res_data =  {
623                         'question_id': que_id,
624                         'date_create': datetime.datetime.now(),
625                         'state': 'done',
626                         'response_id': response_id
627                     }
628                     resp_id = resp_obj.create(cr, uid, res_data)
629                     resp_id_list.append(resp_id)
630                     sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
631                     surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
632                     select_count = 0
633                     numeric_sum = 0
634                     selected_value = []
635                     matrix_list = []
636                     comment_field = False
637                     comment_value = False
638                     response_list = []
639
640                     for key1, val1 in vals.items():
641                         if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
642                             surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
643                             sur_name_read['store_ans'][resp_id].update({key1:val1})
644                             select_count += 1
645
646                         elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
647                             comment_field = True
648                             sur_name_read['store_ans'][resp_id].update({key1:val1})
649                             select_count += 1
650                             surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
651                             continue
652
653                         elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
654                             if len(key1.split('_')) > 2:
655                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
656                                 selected_value.append(val1)
657                                 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
658                             else:
659                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
660                             sur_name_read['store_ans'][resp_id].update({key1:val1})
661                             select_count += 1
662
663                         elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
664                             if not val1:
665                                 comment_value = True
666                             else:
667                                 error = False
668                                 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
669                                     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']:
670                                         error = True
671                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
672                                     error = False
673                                     try:
674                                         if que_rec['comment_valid_type'] == 'must_be_whole_number':
675                                             value = int(val1)
676                                             if value <  que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
677                                                 error = True
678                                         elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
679                                             value = float(val1)
680                                             if value <  que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
681                                                 error = True
682                                         elif que_rec['comment_valid_type'] == 'must_be_date':
683                                             value = datetime.datetime.strptime(val1, "%Y-%m-%d")
684                                             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"):
685                                                 error = True
686                                     except:
687                                         error = True
688                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_email_address':
689                                     import re
690                                     if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
691                                             error = True
692                                 if error:
693                                     for res in resp_id_list:
694                                         sur_name_read['store_ans'].pop(res)
695                                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['comment_valid_err_msg'])))
696
697                                 resp_obj.write(cr, uid, resp_id, {'comment':val1})
698                                 sur_name_read['store_ans'][resp_id].update({key1:val1})
699
700                         elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
701                             resp_obj.write(cr, uid, resp_id, {'comment':val1})
702                             sur_name_read['store_ans'][resp_id].update({key1:val1})
703                             select_count += 1
704
705                         elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single"  or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
706                             error = False
707                             if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
708                                 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']:
709                                     error = True
710                             elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
711                                 error = False
712                                 try:
713                                     if que_rec['validation_type'] == 'must_be_whole_number':
714                                         value = int(val1)
715                                         if value <  que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
716                                             error = True
717                                     elif que_rec['validation_type'] == 'must_be_decimal_number':
718                                         value = float(val1)
719                                         if value <  que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
720                                             error = True
721                                     elif que_rec['validation_type'] == 'must_be_date':
722                                         value = datetime.datetime.strptime(val1, "%Y-%m-%d")
723                                         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"):
724                                             error = True
725                                 except:
726                                     error = True
727                             elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
728                                 import re
729                                 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
730                                         error = True
731                             if error:
732                                 for res in resp_id_list:
733                                     sur_name_read['store_ans'].pop(res)
734                                 raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['validation_valid_err_msg'])))
735
736                             if key1.split('_')[1] == "single" :
737                                 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
738                             else:
739                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
740
741                             sur_name_read['store_ans'][resp_id].update({key1:val1})
742                             select_count += 1
743
744                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
745                             if not val1=="0":
746                                 try:
747                                     numeric_sum += int(val1)
748                                     ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
749                                     sur_name_read['store_ans'][resp_id].update({key1:val1})
750                                     select_count += 1
751                                 except:
752                                     for res in resp_id_list:
753                                         sur_name_read['store_ans'].pop(res)
754                                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' \nPlease enter an integer value " ))
755
756                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
757                             if type(val1) == type('') or type(val1) == type(u''):
758                                 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})
759                                 sur_name_read['store_ans'][resp_id].update({key1:val1})
760                             else:
761                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
762                                 sur_name_read['store_ans'][resp_id].update({key1:True})
763
764                             matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
765                             select_count += 1
766
767                         elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
768                             ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
769                             sur_name_read['store_ans'][resp_id].update({key1:val1})
770                             select_count += 1
771                         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
772
773                     for key,val in vals.items():
774                         if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
775                             for res_id in response_list:
776                                 if key.split('_')[2] in res_id.split('_')[1]:
777                                     a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
778                                     sur_name_read['store_ans'][resp_id].update({key:val})
779
780                     if comment_field and comment_value:
781                         for res in resp_id_list:
782                             sur_name_read['store_ans'].pop(res)
783                         raise osv.except_osv(_('Warning !'), _("'" + que_rec['question']  + "' " + tools.ustr(que_rec['make_comment_field_err_msg'])))
784
785                     if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
786                         for res in resp_id_list:
787                             sur_name_read['store_ans'].pop(res)
788                         raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'"))
789
790                     if not select_count:
791                         resp_obj.write(cr, uid, resp_id, {'state':'skip'})
792
793                     if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
794                         for res in resp_id_list:
795                             sur_name_read['store_ans'].pop(res)
796                         raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg'])))
797
798                     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']:
799                         if matrix_list:
800                             if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
801                             (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
802                             (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
803                             (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
804                             (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'])):
805                                 for res in resp_id_list:
806                                     sur_name_read['store_ans'].pop(res)
807                                 raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
808
809                         elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
810                             (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
811                             (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
812                             (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
813                             (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
814                             for res in resp_id_list:
815                                 sur_name_read['store_ans'].pop(res)
816                             raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
817
818                     if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and  que_rec['is_require_answer'] and select_count <= 0:
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'])))
822
823         else:
824             resp_id_list = []
825             for update in click_update:
826                 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
827                 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
828                 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
829                 resp_id_list.append(update)
830                 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
831                 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
832                 select_count = 0
833                 numeric_sum = 0
834                 selected_value = []
835                 matrix_list = []
836                 comment_field = False
837                 comment_value = False
838                 response_list = []
839
840                 for key, val in vals.items():
841                     ans_id_len = key.split('_')
842                     if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
843                         if val and key.split('_')[1] == "table":
844                             surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
845                             sur_name_read['store_ans'][update].update({key:val})
846                             resp_obj.write(cr, uid, update, {'state': 'done'})
847
848                         elif val and key.split('_')[1] == "otherfield" :
849                             comment_field = True
850                             sur_name_read['store_ans'][update].update({key:val})
851                             select_count += 1
852                             surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
853                             continue
854
855                         elif val and key.split('_')[1] == "selection":
856                             if len(key.split('_')) > 2:
857                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
858                                 selected_value.append(val)
859                                 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
860                             else:
861                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
862                             resp_obj.write(cr, uid, update, {'state': 'done'})
863                             sur_name_read['store_ans'][update].update({key:val})
864                             select_count += 1
865
866                         elif key.split('_')[1] == "other":
867                             if not val:
868                                 comment_value = True
869                             else:
870                                 error = False
871                                 if que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_specific_length':
872                                     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']:
873                                         error = True
874                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
875                                     try:
876                                         if que_rec['comment_valid_type'] == 'must_be_whole_number':
877                                             value = int(val)
878                                             if value <  que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
879                                                 error = True
880                                         elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
881                                             value = float(val)
882                                             if value <  que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
883                                                 error = True
884                                         elif que_rec['comment_valid_type'] == 'must_be_date':
885                                             value = datetime.datetime.strptime(val, "%Y-%m-%d")
886                                             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"):
887                                                 error = True
888                                     except:
889                                         error = True
890                                 elif que_rec['is_comment_require'] and  que_rec['comment_valid_type'] == 'must_be_email_address':
891                                     import re
892                                     if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
893                                             error = True
894                                 if error:
895                                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['comment_valid_err_msg'])))
896                                 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
897                                 sur_name_read['store_ans'][update].update({key:val})
898
899                         elif val and key.split('_')[1] == "comment":
900                             resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
901                             sur_name_read['store_ans'][update].update({key:val})
902                             select_count += 1
903
904                         elif val and (key.split('_')[1] == "single"  or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
905                             error = False
906                             if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
907                                 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']:
908                                     error = True
909                             elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
910                                 error = False
911                                 try:
912                                     if que_rec['validation_type'] == 'must_be_whole_number':
913                                         value = int(val)
914                                         if value <  que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
915                                             error = True
916                                     elif que_rec['validation_type'] == 'must_be_decimal_number':
917                                         value = float(val)
918                                         if value <  que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
919                                             error = True
920                                     elif que_rec['validation_type'] == 'must_be_date':
921                                         value = datetime.datetime.strptime(val, "%Y-%m-%d")
922                                         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"):
923                                             error = True
924                                 except Exception ,e:
925                                     error = True
926                             elif que_rec['is_validation_require'] and  que_rec['validation_type'] == 'must_be_email_address':
927                                 import re
928                                 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
929                                         error = True
930                             if error:
931                                 raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "'  \n" + tools.ustr(que_rec['validation_valid_err_msg'])))
932                             if key.split('_')[1] == "single" :
933                                 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
934                             else:
935                                 resp_obj.write(cr, uid, update, {'state': 'done'})
936                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
937                             sur_name_read['store_ans'][update].update({key:val})
938                             select_count += 1
939
940                         elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
941                             if not val=="0":
942                                 try:
943                                     numeric_sum += int(val)
944                                     resp_obj.write(cr, uid, update, {'state': 'done'})
945                                     ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
946                                     sur_name_read['store_ans'][update].update({key:val})
947                                     select_count += 1
948                                 except:
949                                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' \n Please enter an integer value " ))
950
951                         elif val and len(key.split('_')) == 3:
952                             resp_obj.write(cr, uid, update, {'state': 'done'})
953                             if type(val) == type('') or type(val) == type(u''):
954                                 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})
955                                 sur_name_read['store_ans'][update].update({key:val})
956                             else:
957                                 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
958                                 sur_name_read['store_ans'][update].update({key:True})
959                             matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
960                             select_count += 1
961
962                         elif val and len(key.split('_')) == 2:
963                             resp_obj.write(cr, uid, update, {'state': 'done'})
964                             ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
965                             sur_name_read['store_ans'][update].update({key:val})
966                             select_count += 1
967                         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
968
969                 for key,val in vals.items():
970                     if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
971                         for res_id in response_list:
972                             if key.split('_')[2] in res_id.split('_')[1]:
973                                 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
974                                 sur_name_read['store_ans'][update].update({key:val})
975
976                 if comment_field and comment_value:
977                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question']  + "' " + tools.ustr(que_rec['make_comment_field_err_msg'])))
978
979                 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
980                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "\n you cannot select same answer more than one times'"))
981
982                 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
983                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg'])))
984
985                 if not select_count:
986                     resp_obj.write(cr, uid, update, {'state': 'skip'})
987
988                 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']:
989                     if matrix_list:
990                         if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
991                         (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
992                         (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
993                         (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
994                         (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'])):
995                             raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
996
997                     elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
998                         (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
999                         (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1000                         (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1001                         (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1002                             raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1003
1004                 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and  que_rec['is_require_answer'] and select_count <= 0:
1005                     raise osv.except_osv(_('Warning !'), _("'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg'])))
1006
1007         return True
1008
1009     def action_new_question(self,cr, uid, ids, context):
1010         """
1011         New survey.Question form.
1012
1013         @param self: The object pointer
1014         @param cr: the current row, from the database cursor,
1015         @param uid: the current user’s ID for security checks,
1016         @param ids: List of survey.question.wiz IDs
1017         @param context: A standard dictionary for contextual values
1018         @return : Dictionary value for Open new survey.Qestion form.
1019         """
1020         for key,val in context.items():
1021             if type(key) == type(True):
1022                 context.pop(key)
1023         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1024                             ('name','=','survey_question_wizard_test')])
1025         return {
1026             'view_type': 'form',
1027             "view_mode": 'form',
1028             'res_model': 'survey.question',
1029             'type': 'ir.actions.act_window',
1030             'target': 'new',
1031             'view_id': view_id,
1032             'context': context
1033         }
1034
1035     def action_new_page(self, cr, uid, ids, context):
1036         """
1037         New survey.Page form.
1038
1039         @param self: The object pointer
1040         @param cr: the current row, from the database cursor,
1041         @param uid: the current user’s ID for security checks,
1042         @param ids: List of survey.question.wiz IDs
1043         @param context: A standard dictionary for contextual values
1044         @return : Dictionary value for Open new survey.page form.
1045         """
1046         for key,val in context.items():
1047             if type(key) == type(True):
1048                 context.pop(key)
1049         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1050                                         ('name','=','survey_page_wizard_test')])
1051         return {
1052             'view_type': 'form',
1053             "view_mode": 'form',
1054             'res_model': 'survey.page',
1055             'type': 'ir.actions.act_window',
1056             'target': 'new',
1057             'view_id': view_id,
1058             'context': context
1059         }
1060
1061     def action_edit_page(self,cr, uid, ids, context):
1062         """
1063         Edit survey.page.
1064
1065         @param self: The object pointer
1066         @param cr: the current row, from the database cursor,
1067         @param uid: the current user’s ID for security checks,
1068         @param ids: List of survey.question.wiz IDs
1069         @param context: A standard dictionary for contextual values
1070         @return : Dictionary value for Open Edit survey.page form.
1071         """
1072         for key,val in context.items():
1073             if type(key) == type(True):
1074                 context.pop(key)
1075         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1076                                 ('name','=','survey_page_wizard_test')])
1077         return {
1078             'view_type': 'form',
1079             "view_mode": 'form',
1080             'res_model': 'survey.page',
1081             'type': 'ir.actions.act_window',
1082             'target': 'new',
1083             'res_id': int(context.get('page_id',0)),
1084             'view_id': view_id,
1085             'context': context
1086         }
1087
1088     def action_delete_page(self,cr, uid, ids, context):
1089         """
1090         Delete survey.page.
1091
1092         @param self: The object pointer
1093         @param cr: the current row, from the database cursor,
1094         @param uid: the current user’s ID for security checks,
1095         @param ids: List of survey.question.wiz IDs
1096         @param context: A standard dictionary for contextual values
1097         @return : Dictionary value for Open next survey.page form, but delete the selected page.
1098         """
1099         for key,val in context.items():
1100             if type(key) == type(True):
1101                 context.pop(key)
1102
1103         self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
1104         search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1105                                             ('name','=','Survey Search')])
1106         surv_name_wiz = self.pool.get('survey.name.wiz')
1107         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
1108                     {'transfer':True, 'page_no' : context.get('page_number',False) })
1109         return {
1110             'view_type': 'form',
1111             "view_mode": 'form',
1112             'res_model': 'survey.question.wiz',
1113             'type': 'ir.actions.act_window',
1114             'target': 'new',
1115             'search_view_id':search_id[0],
1116             'context': context
1117         }
1118
1119     def action_edit_question(self,cr, uid, ids, context):
1120         """
1121         Edit survey.question.
1122
1123         @param self: The object pointer
1124         @param cr: the current row, from the database cursor,
1125         @param uid: the current user’s ID for security checks,
1126         @param ids: List of survey.question.wiz IDs
1127         @param context: A standard dictionary for contextual values
1128         @return : Dictionary value for Open Edit survey.question form.
1129         """
1130         for key,val in context.items():
1131             if type(key) == type(True):
1132                 context.pop(key)
1133         view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1134                                 ('name','=','survey_question_wizard_test')])
1135         return {
1136             'view_type': 'form',
1137             "view_mode": 'form',
1138             'res_model': 'survey.question',
1139             'type': 'ir.actions.act_window',
1140             'target': 'new',
1141             'res_id' : int(context.get('question_id',0)),
1142             'view_id': view_id,
1143             'context': context
1144         }
1145
1146     def action_delete_question(self,cr, uid, ids, context):
1147         """
1148         Delete survey.question.
1149
1150         @param self: The object pointer
1151         @param cr: the current row, from the database cursor,
1152         @param uid: the current user’s ID for security checks,
1153         @param ids: List of survey.question.wiz IDs
1154         @param context: A standard dictionary for contextual values
1155         @return : Dictionary value for Open same survey.page form, but delete the selected survey.question in current survey.page.
1156         """
1157         for key,val in context.items():
1158             if type(key) == type(True):
1159                 context.pop(key)
1160
1161         que_obj = self.pool.get('survey.question')
1162         que_obj.unlink(cr, uid, [context.get('question_id',False)])
1163         search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1164                                         ('name','=','Survey Search')])
1165         surv_name_wiz = self.pool.get('survey.name.wiz')
1166         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)],\
1167                      {'transfer':True, 'page_no' : context.get('page_number',0) })
1168         return {
1169                 'view_type': 'form',
1170                 "view_mode": 'form',
1171                 'res_model': 'survey.question.wiz',
1172                 'type': 'ir.actions.act_window',
1173                 'target': 'new',
1174                 'search_view_id': search_id[0],
1175                 'context': context
1176                 }
1177
1178     def action_forward_previous(self, cr, uid, ids, context=None):
1179         """
1180         Goes to previous Survey Answer.
1181
1182         @param self: The object pointer
1183         @param cr: the current row, from the database cursor,
1184         @param uid: the current user’s ID for security checks,
1185         @param ids: List of survey.question.wiz IDs
1186         @param context: A standard dictionary for contextual values
1187         @return : Dictionary value for Open Previous Answer form.
1188         """
1189         search_obj = self.pool.get('ir.ui.view')
1190         surv_name_wiz = self.pool.get('survey.name.wiz')
1191         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1192                                               ('name','=','Survey Search')])
1193         wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1194         context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
1195
1196         if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1197             return {}
1198         return {
1199             'view_type': 'form',
1200             "view_mode": 'form',
1201             'res_model': 'survey.question.wiz',
1202             'type': 'ir.actions.act_window',
1203             'target': 'new',
1204             'search_view_id': search_id[0],
1205             'context': context
1206         }
1207
1208     def action_forward_next(self, cr, uid, ids, context=None):
1209         """
1210         Goes to Next Survey Answer.
1211
1212         @param self: The object pointer
1213         @param cr: the current row, from the database cursor,
1214         @param uid: the current user’s ID for security checks,
1215         @param ids: List of survey.question.wiz IDs
1216         @param context: A standard dictionary for contextual values
1217         @return : Dictionary value for Open Next Answer form.
1218         """
1219         search_obj = self.pool.get('ir.ui.view')
1220         surv_name_wiz = self.pool.get('survey.name.wiz')
1221         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1222                                     ('name','=','Survey Search')])
1223         wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1224         context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
1225
1226         if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1227             return {}
1228         return {
1229             'view_type': 'form',
1230             "view_mode": 'form',
1231             'res_model': 'survey.question.wiz',
1232             'type': 'ir.actions.act_window',
1233             'target': 'new',
1234             'search_view_id': search_id[0],
1235             'context': context
1236         }
1237
1238     def action_next(self, cr, uid, ids, context=None):
1239         """
1240         Goes to Next page.
1241
1242         @param self: The object pointer
1243         @param cr: the current row, from the database cursor,
1244         @param uid: the current user’s ID for security checks,
1245         @param ids: List of survey.question.wiz IDs
1246         @param context: A standard dictionary for contextual values
1247         @return : Dictionary value for Open Next survey.page form.
1248         """
1249         surv_name_wiz = self.pool.get('survey.name.wiz')
1250         search_obj = self.pool.get('ir.ui.view')
1251         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1252         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
1253         return {
1254             'view_type': 'form',
1255             "view_mode": 'form',
1256             'res_model': 'survey.question.wiz',
1257             'type': 'ir.actions.act_window',
1258             'target': 'new',
1259             'search_view_id': search_id[0],
1260             'context': context
1261         }
1262
1263     def action_previous(self, cr, uid, ids, context=None):
1264         """
1265         Goes to previous page.
1266
1267         @param self: The object pointer
1268         @param cr: the current row, from the database cursor,
1269         @param uid: the current user’s ID for security checks,
1270         @param ids: List of survey.question.wiz IDs
1271         @param context: A standard dictionary for contextual values
1272         @return : Dictionary value for Open Previous survey.page form.
1273         """
1274         surv_name_wiz = self.pool.get('survey.name.wiz')
1275         search_obj = self.pool.get('ir.ui.view')
1276         search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1277                                     ('name','=','Survey Search')])
1278         surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
1279         return {
1280             'view_type': 'form',
1281             "view_mode": 'form',
1282             'res_model': 'survey.question.wiz',
1283             'type': 'ir.actions.act_window',
1284             'target': 'new',
1285             'search_view_id': search_id[0],
1286             'context': context
1287         }
1288
1289 survey_question_wiz()
1290
1291 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: