Merge lp:~vauxoo/addons-vauxoo/jose_answer_survey into lp:addons-vauxoo/7.0

Status: Superseded
Proposed branch: lp:~vauxoo/addons-vauxoo/jose_answer_survey
Merge into: lp:addons-vauxoo/7.0
Diff against target: 898 lines (+830/-0)
11 files modified
answer_survey/__init__.py (+2/-0)
answer_survey/__openerp__.py (+57/-0)
answer_survey/model/__init__.py (+1/-0)
answer_survey/model/survey.py (+42/-0)
answer_survey/security/groups_survey.xml (+10/-0)
answer_survey/static/src/css/survey.css (+25/-0)
answer_survey/view/answer_survey_menu.xml (+11/-0)
answer_survey/wizard/__init__.py (+25/-0)
answer_survey/wizard/survey_answer.xml (+16/-0)
answer_survey/wizard/survey_selection.py (+475/-0)
answer_survey/wizard/survey_send_invitation.py (+166/-0)
To merge this branch: bzr merge lp:~vauxoo/addons-vauxoo/jose_answer_survey
Reviewer Review Type Date Requested Status
Nhomar - Vauxoo Pending
Review via email: mp+188145@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-06.

Description of the change

Added new branch answer_surver

This brach inherits the features of module survy from main addons, and modify the themes for use the new vauxoo portal theme

To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'answer_survey'
=== added file 'answer_survey/__init__.py'
--- answer_survey/__init__.py 1970-01-01 00:00:00 +0000
+++ answer_survey/__init__.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,2 @@
1import model
2import wizard
03
=== added file 'answer_survey/__openerp__.py'
--- answer_survey/__openerp__.py 1970-01-01 00:00:00 +0000
+++ answer_survey/__openerp__.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,57 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
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.
11#
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.
16#
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/>.
19#
20##############################################################################
21{
22 'name' : 'Answer Survey',
23 'version' : '0.1',
24 'author' : 'Vauxoo',
25 'category' : '',
26 'description' : """
27
28 """,
29 'website': 'http://www.vauxoo.com',
30 'images' : [],
31 'depends' : [
32 'survey',
33 'web_bootstrap3',
34 'portal_crm_vauxoo',
35 'web_fontawesome',
36 ],
37 'data': [
38 'security/groups_survey.xml',
39 'wizard/survey_answer.xml',
40 'view/answer_survey_menu.xml',
41 ],
42 'js': [
43 ],
44 'qweb' : [
45 ],
46 'css':[
47 'static/src/css/survey.css',
48 ],
49 'demo': [
50 ],
51 'test': [
52 ],
53 'installable': True,
54 'auto_install': False,
55}
56# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
57
058
=== added directory 'answer_survey/data'
=== added directory 'answer_survey/demo'
=== added directory 'answer_survey/i18n'
=== added directory 'answer_survey/model'
=== added file 'answer_survey/model/__init__.py'
--- answer_survey/model/__init__.py 1970-01-01 00:00:00 +0000
+++ answer_survey/model/__init__.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,1 @@
1import survey
02
=== added file 'answer_survey/model/survey.py'
--- answer_survey/model/survey.py 1970-01-01 00:00:00 +0000
+++ answer_survey/model/survey.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,42 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
6#
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.
11#
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.
16#
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/>.
19#
20##############################################################################
21
22import copy
23from datetime import datetime
24from dateutil.relativedelta import relativedelta
25from time import strftime
26import os
27
28from openerp import netsvc, tools
29from openerp.osv import fields, osv
30from openerp.tools.translate import _
31
32
33class survey(osv.Model):
34 _inherit = 'survey'
35
36 def fill_survey(self, cr, uid, ids, context=None):
37 res = super(survey,self).fill_survey(cr, uid, ids, context)
38 res.update( {
39 'target': 'inline',
40 })
41 return res
42# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
043
=== added directory 'answer_survey/report'
=== added directory 'answer_survey/security'
=== added file 'answer_survey/security/groups_survey.xml'
--- answer_survey/security/groups_survey.xml 1970-01-01 00:00:00 +0000
+++ answer_survey/security/groups_survey.xml 2013-09-27 19:15:29 +0000
@@ -0,0 +1,10 @@
1<?xml version='1.0' encoding='utf-8'?>
2<openerp>
3<data noupdate="1">
4
5 <record id="only_answer_menu" model="res.groups">
6 <field name="name">Answer Survey Menu</field>
7 </record>
8
9</data>
10</openerp>
011
=== added directory 'answer_survey/static'
=== added directory 'answer_survey/static/src'
=== added directory 'answer_survey/static/src/css'
=== added file 'answer_survey/static/src/css/survey.css'
--- answer_survey/static/src/css/survey.css 1970-01-01 00:00:00 +0000
+++ answer_survey/static/src/css/survey.css 2013-09-27 19:15:29 +0000
@@ -0,0 +1,25 @@
1.icon-3x {
2 padding:10px;
3}
4
5.btn.btn-large.btn-primary {
6 color:black;
7 height:28px;
8 width:140px;
9 position:relative;
10}
11.oe_e span{
12 height:32px;
13 line-height:25px;
14 text-align:center;
15 left:60px;
16 position:absolute;
17 top:0;
18 font-size: 34px;
19}
20button.answer_exit.btn.btn-large.btn-primary {
21 color:black;
22 background-color:red;
23 width:10em;
24 height:28px;
25}
026
=== added directory 'answer_survey/static/src/js'
=== added directory 'answer_survey/static/src/xml'
=== added directory 'answer_survey/view'
=== added file 'answer_survey/view/answer_survey_menu.xml'
--- answer_survey/view/answer_survey_menu.xml 1970-01-01 00:00:00 +0000
+++ answer_survey/view/answer_survey_menu.xml 2013-09-27 19:15:29 +0000
@@ -0,0 +1,11 @@
1<?xml version="1.0" ?>
2<openerp>
3 <data>
4
5 <menuitem id="answer_survey_only_menu"
6 groups='answer_survey.only_answer_menu'
7 sequence='1'
8 name='Answer Your Survies'
9 action="survey.action_view_survey_name"/>
10 </data>
11</openerp>
012
=== added directory 'answer_survey/wizard'
=== added file 'answer_survey/wizard/__init__.py'
--- answer_survey/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ answer_survey/wizard/__init__.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,25 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
6#
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.
11#
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.
16#
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/>.
19#
20##############################################################################
21
22import survey_send_invitation
23import survey_selection
24
25# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
026
=== added file 'answer_survey/wizard/survey_answer.xml'
--- answer_survey/wizard/survey_answer.xml 1970-01-01 00:00:00 +0000
+++ answer_survey/wizard/survey_answer.xml 2013-09-27 19:15:29 +0000
@@ -0,0 +1,16 @@
1<?xml version="1.0" ?>
2<openerp>
3 <data>
4
5 <record id="survey.action_view_survey_name"
6 model="ir.actions.act_window">
7 <field name="name">Give Survey Answer</field>
8 <field name="type">ir.actions.act_window</field>
9 <field name="res_model">survey.name.wiz</field>
10 <field name="view_type">form</field>
11 <field name="view_mode">form</field>
12 <field name="target">inline</field>
13 </record>
14
15 </data>
16</openerp>
017
=== added file 'answer_survey/wizard/survey_selection.py'
--- answer_survey/wizard/survey_selection.py 1970-01-01 00:00:00 +0000
+++ answer_survey/wizard/survey_selection.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,475 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
6#
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.
11#
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.
16#
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/>.
19#
20##############################################################################
21
22from lxml import etree
23import os
24from openerp import addons, netsvc, tools
25from openerp.tools import to_xml
26from openerp.tools.safe_eval import safe_eval
27from openerp.osv import fields, osv
28from openerp.tools.translate import _
29
30class survey_name_wiz(osv.TransientModel):
31 _inherit = 'survey.name.wiz'
32
33 def action_next(self, cr, uid, ids, context=None):
34 res = super(survey_name_wiz, self).action_next(cr, uid, ids, context)
35
36 res.update( {
37 'target': 'inline',
38 })
39 return res
40
41class survey_question_wiz(osv.TransientModel):
42 _inherit = 'survey.question.wiz'
43
44 def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
45 """
46 Fields View Get method :- generate the new view and display the survey pages of selected survey.
47 """
48
49 if context is None:
50 context = {}
51 result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
52 view_type, {}, toolbar,submenu)
53
54 surv_name_wiz = self.pool.get('survey.name.wiz')
55 survey_obj = self.pool.get('survey')
56 page_obj = self.pool.get('survey.page')
57 que_obj = self.pool.get('survey.question')
58 ans_obj = self.pool.get('survey.answer')
59 sur_response_obj = self.pool.get('survey.response')
60 que_col_head = self.pool.get('survey.question.column.heading')
61 user_obj = self.pool.get('res.users')
62 mail_message = self.pool.get('mail.message')
63
64 if view_type in ['form']:
65 wiz_id = 0
66 sur_name_rec = None
67 if 'sur_name_id' in context:
68 sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
69 elif 'survey_id' in context:
70 res_data = {
71 'survey_id': context.get('survey_id', False),
72 'page_no': -1,
73 'page': 'next',
74 'transfer': 1,
75 'response': 0
76 }
77 wiz_id = surv_name_wiz.create(cr, uid, res_data)
78 sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id, context=context)
79 context.update({'sur_name_id' :wiz_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 and sur_name_rec.survey_id:
88 survey_id = sur_name_rec.survey_id.id
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 sur_rec = survey_obj.browse(cr, uid, survey_id, context=context)
99 p_id = map(lambda x:x.id, sur_rec.page_ids)
100 total_pages = len(p_id)
101 pre_button = False
102 readonly = 0
103
104 if context.get('response_id', False) \
105 and int(context['response_id'][0]) > 0:
106 readonly = 1
107
108 if not sur_name_rec.page_no + 1 :
109 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
110
111 sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
112 page_number = int(sur_name_rec.page_no)
113 if sur_name_read.transfer or not sur_name_rec.page_no + 1:
114 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
115 flag = False
116 fields = {}
117 if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
118 if total_pages > sur_name_rec.page_no + 1:
119 if ((context.has_key('active') and not context.get('active', False)) \
120 or not context.has_key('active')) and not sur_name_rec.page_no + 1:
121 if sur_rec.state != "open" :
122 raise osv.except_osv(_('Warning!'),_("You cannot answer because the survey is not open."))
123 cr.execute('select count(id) from survey_history where user_id=%s\
124 and survey_id=%s', (uid,survey_id))
125 res = cr.fetchone()[0]
126 user_limit = survey_obj.browse(cr, uid, survey_id)
127 user_limit = user_limit.response_user
128 if user_limit and res >= user_limit:
129 raise osv.except_osv(_('Warning!'),_("You cannot answer this survey more than %s times.") % (user_limit))
130
131 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:
132 survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
133
134 p_id = p_id[sur_name_rec.page_no + 1]
135 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
136 flag = True
137 page_number += 1
138 if sur_name_rec.page_no > - 1:
139 pre_button = True
140 else:
141 flag = True
142 else:
143 if sur_name_rec.page_no != 0:
144 p_id = p_id[sur_name_rec.page_no - 1]
145 surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
146 {'page_no' : sur_name_rec.page_no - 1})
147 flag = True
148 page_number -= 1
149
150 if sur_name_rec.page_no > 1:
151 pre_button = True
152 if flag:
153 pag_rec = page_obj.browse(cr, uid, p_id, context=context)
154 note = False
155 question_ids = []
156 if pag_rec:
157 title = pag_rec.title
158 note = pag_rec.note
159 question_ids = pag_rec.question_ids
160 else:
161 title = sur_rec.title
162 form = etree.Element('form', {'class':'bs3 bs3-form-bg bs3-footer','string': tools.ustr(title)})
163 section = etree.SubElement(form, 'section', {'class': 'bgvauxoo'})
164 xml_form = etree.SubElement(section, 'div', {'class': 'container'})
165 if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
166 context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
167 xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
168 etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
169 etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
170 etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
171 etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
172
173 # FP Note
174 xml_group = xml_form
175
176 if context.has_key('response_id') and context.get('response_id', False) \
177 and int(context.get('response_id',0)[0]) > 0:
178 # TODO: l10n, cleanup this code to make it readable. Or template?
179 xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
180 record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
181 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"})
182 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"})
183 if context.get('response_no',0) > 0:
184 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
185 if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
186 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)})
187
188 if wiz_id:
189 fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
190 etree.SubElement(xml_form, 'field', {'widget':'FieldCharBS3','invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0),'modifiers':'{"invisible":true}'})
191
192 if note:
193 xml_group_note = etree.SubElement(xml_form, 'group', {'col': '1','colspan': '4'})
194 for que_test in note.split('\n'):
195 etree.SubElement(xml_group_note, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
196 que_ids = question_ids
197 qu_no = 0
198
199 for que in que_ids:
200 qu_no += 1
201 que_rec = que_obj.browse(cr, uid, que.id, context=context)
202 descriptive_text = ""
203 separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
204 if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
205 star = '*'
206 else:
207 star = ''
208 if context.has_key('active') and context.get('active',False) and \
209 context.has_key('edit'):
210 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
211
212 xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2',
213 'colspan': '2'})
214 context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
215 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
216 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
217 else:
218 etree.SubElement(xml_form, 'newline')
219 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
220
221 ans_ids = que_rec.answer_choice_ids
222 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
223
224 if que_rec.type == 'multiple_choice_only_one_ans':
225 selection = []
226 for ans in ans_ids:
227 selection.append((tools.ustr(ans.id), ans.answer))
228 xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
229 etree.SubElement(xml_group, 'field', {'nolabel':'True','class':'dropdown-menus','readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
230 fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"}
231
232 elif que_rec.type == 'multiple_choice_multiple_ans':
233 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
234 for ans in ans_ids:
235 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
236 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
237
238 elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
239 if que_rec.comment_column:
240 col = "4"
241 colspan = "4"
242 else:
243 col = "2"
244 colspan = "2"
245 xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
246 for row in ans_ids:
247 etree.SubElement(xml_group, 'newline')
248 etree.SubElement(xml_group, 'field', {'nolabel':'True','readonly': str(readonly), 'class':'dropdown-menus','name': tools.ustr(que.id) + "_selection_" + tools.ustr(row.id),'string':to_xml(tools.ustr(row.answer))})
249 selection = [('','')]
250 for col in que_rec.column_heading_ids:
251 selection.append((str(col.id), col.title))
252 fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
253 if que_rec.comment_column:
254 fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
255 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
256
257 elif que_rec.type == 'matrix_of_choices_only_multi_ans':
258 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
259 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
260 for col in que_rec.column_heading_ids:
261 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
262 for row in ans_ids:
263 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
264 for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
265 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
266 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
267
268 elif que_rec.type == 'matrix_of_drop_down_menus':
269 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
270 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
271 for col in que_rec.column_heading_ids:
272 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
273 for row in ans_ids:
274 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
275 for col in que_rec.column_heading_ids:
276 selection = []
277 if col.menu_choice:
278 for item in col.menu_choice.split('\n'):
279 if item and not item.strip() == '': selection.append((item ,item))
280 etree.SubElement(xml_group, 'field', {'nolabel':'True','class':'dropdown-menus','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
281 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
282
283 elif que_rec.type == 'multiple_textboxes':
284 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
285 type = "char"
286 if que_rec.is_validation_require:
287 if que_rec.validation_type in ['must_be_whole_number']:
288 type = "integer"
289 elif que_rec.validation_type in ['must_be_decimal_number']:
290 type = "float"
291 elif que_rec.validation_type in ['must_be_date']:
292 type = "date"
293 for ans in ans_ids:
294 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
295 if type == "char" :
296 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
297 else:
298 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
299
300 elif que_rec.type == 'numerical_textboxes':
301 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
302 for ans in ans_ids:
303 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
304 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
305
306 elif que_rec.type == 'date':
307 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
308 for ans in ans_ids:
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':'date', 'string':ans.answer}
311
312 elif que_rec.type == 'date_and_time':
313 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
314 for ans in ans_ids:
315 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
316 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
317
318 elif que_rec.type == 'descriptive_text':
319 if que_rec.descriptive_text:
320 for que_test in que_rec.descriptive_text.split('\n'):
321 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
322
323 elif que_rec.type == 'single_textbox':
324 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
325 fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
326
327 elif que_rec.type == 'comment':
328 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
329 fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
330
331 elif que_rec.type == 'table':
332 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
333 for col in que_rec.column_heading_ids:
334 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
335 for row in range(0,que_rec.no_of_rows):
336 for col in que_rec.column_heading_ids:
337 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
338 fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
339
340 elif que_rec.type == 'multiple_textboxes_diff_type':
341 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
342 for ans in ans_ids:
343 if ans.type == "email" :
344 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
345 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
346 else:
347 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
348 if ans.type == "char" :
349 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
350 elif ans.type in ['integer','float','date','datetime']:
351 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
352 else:
353 selection = []
354 if ans.menu_choice:
355 for item in ans.menu_choice.split('\n'):
356 if item and not item.strip() == '': selection.append((item ,item))
357 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
358
359 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:
360 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:
361 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
362 fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
363 if que_rec.comment_field_type == 'char':
364 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
365 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
366 elif que_rec.comment_field_type == 'text':
367 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
368 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
369 else:
370 if que_rec.comment_field_type == 'char':
371 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
372 etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
373 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
374 elif que_rec.comment_field_type == 'text':
375 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
376 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
377 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
378
379 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '8', 'colspan': '1', 'width':"100%"})
380
381 if pre_button:
382 etree.SubElement(xml_footer, 'label', {'string': ""})
383 etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':"e",'type':"object",'class':"answer_exit btn btn-primary btn-large oe_e"})
384 but_string = "Next"
385 if int(page_number) + 1 == total_pages:
386 but_string = "Done"
387 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)):
388 etree.SubElement(xml_footer, 'label', {'string': ""})
389 etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
390 elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
391 etree.SubElement(xml_footer, 'label', {'string': ""})
392 etree.SubElement(xml_footer, 'button', {'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
393 elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
394 etree.SubElement(xml_footer, 'label', {'string': ""})
395 etree.SubElement(xml_footer, 'button', {'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context), 'class':"answer_exit btn btn-primary btn-large"})
396 else:
397 etree.SubElement(xml_footer, 'label', {'string': ""})
398 etree.SubElement(xml_footer, 'button', {'class': "btn btn-primary btn-large oe_e",'name':"action_next",'string':but_string == 'Next'and '/' or '8','type':"object",'context' : tools.ustr(context)})
399 etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':"c",'class':"answer_exit btn btn-primary btn-large oe_e"})
400 etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
401
402 root = form.getroottree()
403 result['arch'] = etree.tostring(root)
404 result['fields'] = fields
405 print 'rooooooooot',etree.tostring(root)
406 print 'fields', fields
407 result['context'] = context
408 else:
409 survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
410 sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
411
412 # mark the survey request as done; call 'survey_req_done' on its actual model
413 survey_req_obj = self.pool.get(context.get('active_model'))
414 if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
415 survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
416
417 if sur_rec.send_response:
418 survey_data = survey_obj.browse(cr, uid, survey_id)
419 response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
420 report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
421 attachments = {}
422 pdf_filename = addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf"
423 if os.path.exists(pdf_filename):
424 file = open(pdf_filename)
425 file_data = ""
426 while 1:
427 line = file.readline()
428 file_data += line
429 if not line:
430 break
431
432 attachments[survey_data.title + ".pdf"] = file_data
433 file.close()
434 os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
435 context.update({'response_id':response_id})
436 user_email = user_obj.browse(cr, uid, uid, context).email
437 resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
438
439 if user_email and resp_email:
440 user_name = user_obj.browse(cr, uid, uid, context=context).name
441 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."
442 vals = {'state': 'outgoing',
443 'subject': "Survey Answer Of " + user_name,
444 'body_html': '<pre>%s</pre>' % mail,
445 'email_to': [resp_email],
446 'email_from': user_email}
447 if attachments:
448 vals['attachment_ids'] = [(0,0,{'name': a_name,
449 'datas_fname': a_name,
450 'datas': str(a_content).encode('base64')})
451 for a_name, a_content in attachments.items()]
452 self.pool.get('mail.mail').create(cr, uid, vals, context=context)
453
454 xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
455 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '6', 'colspan': '4' ,'class': 'oe_survey_title_height'})
456
457 etree.SubElement(xml_form, 'separator', {'string': 'Survey Completed', 'colspan': "4"})
458 etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
459 etree.SubElement(xml_form, 'newline')
460 etree.SubElement(xml_footer, 'button', {'special':"cancel",'string':"OK",'colspan':"2",'class':'oe_highlight'})
461 root = xml_form.getroottree()
462 result['arch'] = etree.tostring(root)
463 result['fields'] = {}
464 result['context'] = context
465 return result
466
467
468 def action_next(self, cr, uid, ids, context=None):
469 res = super(survey_question_wiz, self).action_next(cr, uid, ids, context)
470
471 res.update( {
472 'target': 'inline',
473 })
474 return res
475
0476
=== added file 'answer_survey/wizard/survey_send_invitation.py'
--- answer_survey/wizard/survey_send_invitation.py 1970-01-01 00:00:00 +0000
+++ answer_survey/wizard/survey_send_invitation.py 2013-09-27 19:15:29 +0000
@@ -0,0 +1,166 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>)
6#
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
11#
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
16#
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/>
19#
20##############################################################################
21
22import time
23from random import choice
24import string
25import os
26import datetime
27import socket
28
29from openerp import addons, netsvc, tools
30from openerp.osv import fields, osv
31from openerp.tools.translate import _
32
33
34class survey_send_invitation(osv.TransientModel):
35 _inherit = 'survey.send.invitation'
36
37 def action_send(self, cr, uid, ids, context=None):
38 if context is None:
39 context = {}
40 record = self.read(cr, uid, ids, [],context=context)
41 survey_ids = context.get('active_ids', [])
42 record = record and record[0]
43 partner_ids = record['partner_ids']
44 user_ref= self.pool.get('res.users')
45 survey_ref= self.pool.get('survey')
46 mail_message = self.pool.get('mail.message')
47
48 model_data_obj = self.pool.get('ir.model.data')
49 group_ids = []
50 group_id = model_data_obj._get_id(cr, uid, 'base', 'group_survey_user')
51 group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
52 group_id = model_data_obj._get_id(cr, uid, 'answer_survey', 'only_answer_menu')
53 group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
54 group_id = model_data_obj._get_id(cr, uid, 'portal', 'group_portal')
55 group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
56
57 act_id = self.pool.get('ir.actions.act_window')
58 act_id = act_id.search(cr, uid, [('res_model', '=' , 'survey.name.wiz'), \
59 ('view_type', '=', 'form')])
60 out = "login,password\n"
61 skipped = 0
62 existing = ""
63 created = ""
64 error = ""
65 new_user = []
66 attachments = {}
67 current_sur = survey_ref.browse(cr, uid, context.get('active_id'), context=context)
68 exist_user = current_sur.invited_user_ids
69 if exist_user:
70 for use in exist_user:
71 new_user.append(use.id)
72 for id in survey_ref.browse(cr, uid, survey_ids):
73 report = self.create_report(cr, uid, [id.id], 'report.survey.form', id.title)
74 file = open(addons.get_module_resource('survey', 'report') + id.title +".pdf")
75 file_data = ""
76 while 1:
77 line = file.readline()
78 file_data += line
79 if not line:
80 break
81 file.close()
82 attachments[id.title +".pdf"] = file_data
83 os.remove(addons.get_module_resource('survey', 'report') + id.title +".pdf")
84
85 for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids):
86 if not partner.email:
87 skipped+= 1
88 continue
89 user = user_ref.search(cr, uid, [('login', "=", partner.email)])
90 if user:
91 if user[0] not in new_user:
92 new_user.append(user[0])
93 user = user_ref.browse(cr, uid, user[0])
94 user_ref.write(cr, uid, user.id, {'survey_id':[[6, 0, survey_ids]]})
95 mail = record['mail']%{'login':partner.email, 'passwd':user.password, \
96 'name' : partner.name}
97 if record['send_mail_existing']:
98 vals = {
99 'state': 'outgoing',
100 'subject': record['mail_subject_existing'],
101 'body_html': '<pre>%s</pre>' % mail,
102 'email_to': partner.email,
103 'email_from': record['mail_from'],
104 }
105 self.pool.get('mail.mail').create(cr, uid, vals, context=context)
106 existing+= "- %s (Login: %s, Password: %s)\n" % (user.name, partner.email, \
107 user.password)
108 continue
109
110 passwd= self.genpasswd()
111 out+= partner.email + ',' + passwd + '\n'
112 mail= record['mail'] % {'login' : partner.email, 'passwd' : passwd, 'name' : partner.name}
113 if record['send_mail']:
114 vals = {
115 'state': 'outgoing',
116 'subject': record['mail_subject'],
117 'body_html': '<pre>%s</pre>' % mail,
118 'email_to': partner.email,
119 'email_from': record['mail_from'],
120 }
121 if attachments:
122 vals['attachment_ids'] = [(0,0,{'name': a_name,
123 'datas_fname': a_name,
124 'datas': str(a_content).encode('base64')})
125 for a_name, a_content in attachments.items()]
126 ans = self.pool.get('mail.mail').create(cr, uid, vals, context=context)
127 if ans:
128 res_data = {'name': partner.name or _('Unknown'),
129 'login': partner.email,
130 'password': passwd,
131 'address_id': partner.id,
132 'groups_id': [[6, 0, group_ids]],
133 'action_id': act_id[0],
134 'survey_id': [[6, 0, survey_ids]]
135 }
136 user = user_ref.create(cr, uid, res_data)
137 if user not in new_user:
138 new_user.append(user)
139 created+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
140 partner.email, passwd)
141 else:
142 error+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
143 partner.email, passwd)
144
145 new_vals = {}
146 new_vals.update({'invited_user_ids':[[6,0,new_user]]})
147 survey_ref.write(cr, uid, context.get('active_id'),new_vals)
148 note= ""
149 if created:
150 note += 'Created users:\n%s\n\n' % (created)
151 if existing:
152 note +='Already existing users:\n%s\n\n' % (existing)
153 if skipped:
154 note += "%d contacts where ignored (an email address is missing).\n\n" % (skipped)
155 if error:
156 note += 'Email not send successfully:\n====================\n%s\n' % (error)
157 context.update({'note' : note})
158 return {
159 'view_type': 'form',
160 "view_mode": 'form',
161 'res_model': 'survey.send.invitation.log',
162 'type': 'ir.actions.act_window',
163 'target': 'new',
164 'context': context
165 }
166# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: