Merge lp:~vauxoo/addons-vauxoo/7.0-user_wzd-dev-carlos into lp:addons-vauxoo/7.0

Status: Merged
Merged at revision: 884
Proposed branch: lp:~vauxoo/addons-vauxoo/7.0-user_wzd-dev-carlos
Merge into: lp:addons-vauxoo/7.0
Diff against target: 1321 lines (+1201/-0)
19 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)
user_wzd/__init__.py (+2/-0)
user_wzd/__openerp__.py (+52/-0)
user_wzd/i18n/es.po (+62/-0)
user_wzd/i18n/es_MX.po (+62/-0)
user_wzd/model/__init__.py (+1/-0)
user_wzd/wizard/__init__.py (+1/-0)
user_wzd/wizard/res_users_view.xml (+44/-0)
user_wzd/wizard/res_users_wzd.py (+147/-0)
To merge this branch: bzr merge lp:~vauxoo/addons-vauxoo/7.0-user_wzd-dev-carlos
Reviewer Review Type Date Requested Status
Jose Antonio Morales Ponce(vauxoo) - - http://www.vauxoo.com Approve
Isaac López Zúñiga Pending
Sabrina Romero - http://www.vauxoo.com Pending
Moisés López - http://www.vauxoo.com Pending
Review via email: mp+192078@code.launchpad.net

Description of the change

se agregó módulo que crea los empleados de los usuarios, y se asigne la relación hr_employee: user_id, solo y solo si ya no hay otro registro de empleado asignado al usuario en cuestión.

Le agregue una pequeña modificacion, para trabajar con los users seleccionados desde la vista en tree

To post a comment you must log in.
Revision history for this message
Jose Antonio Morales Ponce(vauxoo) - - http://www.vauxoo.com (josemoralesp) wrote :

Le hice una pequeña modificacion, para trabajar con los users seleccionados desde la vista en tree

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'answer_survey'
2=== added file 'answer_survey/__init__.py'
3--- answer_survey/__init__.py 1970-01-01 00:00:00 +0000
4+++ answer_survey/__init__.py 2013-10-22 03:10:23 +0000
5@@ -0,0 +1,2 @@
6+import model
7+import wizard
8
9=== added file 'answer_survey/__openerp__.py'
10--- answer_survey/__openerp__.py 1970-01-01 00:00:00 +0000
11+++ answer_survey/__openerp__.py 2013-10-22 03:10:23 +0000
12@@ -0,0 +1,57 @@
13+# -*- coding: utf-8 -*-
14+##############################################################################
15+#
16+# OpenERP, Open Source Management Solution
17+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
18+#
19+# This program is free software: you can redistribute it and/or modify
20+# it under the terms of the GNU Affero General Public License as
21+# published by the Free Software Foundation, either version 3 of the
22+# License, or (at your option) any later version.
23+#
24+# This program is distributed in the hope that it will be useful,
25+# but WITHOUT ANY WARRANTY; without even the implied warranty of
26+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+# GNU Affero General Public License for more details.
28+#
29+# You should have received a copy of the GNU Affero General Public License
30+# along with this program. If not, see <http://www.gnu.org/licenses/>.
31+#
32+##############################################################################
33+{
34+ 'name' : 'Answer Survey',
35+ 'version' : '0.1',
36+ 'author' : 'Vauxoo',
37+ 'category' : '',
38+ 'description' : """
39+
40+ """,
41+ 'website': 'http://www.vauxoo.com',
42+ 'images' : [],
43+ 'depends' : [
44+ 'survey',
45+ 'web_bootstrap3',
46+ 'portal_crm_vauxoo',
47+ 'web_fontawesome',
48+ ],
49+ 'data': [
50+ 'security/groups_survey.xml',
51+ 'wizard/survey_answer.xml',
52+ 'view/answer_survey_menu.xml',
53+ ],
54+ 'js': [
55+ ],
56+ 'qweb' : [
57+ ],
58+ 'css':[
59+ 'static/src/css/survey.css',
60+ ],
61+ 'demo': [
62+ ],
63+ 'test': [
64+ ],
65+ 'installable': True,
66+ 'auto_install': False,
67+}
68+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
69+
70
71=== added directory 'answer_survey/data'
72=== added directory 'answer_survey/demo'
73=== added directory 'answer_survey/i18n'
74=== added directory 'answer_survey/model'
75=== added file 'answer_survey/model/__init__.py'
76--- answer_survey/model/__init__.py 1970-01-01 00:00:00 +0000
77+++ answer_survey/model/__init__.py 2013-10-22 03:10:23 +0000
78@@ -0,0 +1,1 @@
79+import survey
80
81=== added file 'answer_survey/model/survey.py'
82--- answer_survey/model/survey.py 1970-01-01 00:00:00 +0000
83+++ answer_survey/model/survey.py 2013-10-22 03:10:23 +0000
84@@ -0,0 +1,42 @@
85+# -*- encoding: utf-8 -*-
86+##############################################################################
87+#
88+# OpenERP, Open Source Management Solution
89+# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
90+#
91+# This program is free software: you can redistribute it and/or modify
92+# it under the terms of the GNU Affero General Public License as
93+# published by the Free Software Foundation, either version 3 of the
94+# License, or (at your option) any later version.
95+#
96+# This program is distributed in the hope that it will be useful,
97+# but WITHOUT ANY WARRANTY; without even the implied warranty of
98+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99+# GNU Affero General Public License for more details.
100+#
101+# You should have received a copy of the GNU Affero General Public License
102+# along with this program. If not, see <http://www.gnu.org/licenses/>.
103+#
104+##############################################################################
105+
106+import copy
107+from datetime import datetime
108+from dateutil.relativedelta import relativedelta
109+from time import strftime
110+import os
111+
112+from openerp import netsvc, tools
113+from openerp.osv import fields, osv
114+from openerp.tools.translate import _
115+
116+
117+class survey(osv.Model):
118+ _inherit = 'survey'
119+
120+ def fill_survey(self, cr, uid, ids, context=None):
121+ res = super(survey,self).fill_survey(cr, uid, ids, context)
122+ res.update( {
123+ 'target': 'inline',
124+ })
125+ return res
126+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
127
128=== added directory 'answer_survey/report'
129=== added directory 'answer_survey/security'
130=== added file 'answer_survey/security/groups_survey.xml'
131--- answer_survey/security/groups_survey.xml 1970-01-01 00:00:00 +0000
132+++ answer_survey/security/groups_survey.xml 2013-10-22 03:10:23 +0000
133@@ -0,0 +1,10 @@
134+<?xml version='1.0' encoding='utf-8'?>
135+<openerp>
136+<data noupdate="1">
137+
138+ <record id="only_answer_menu" model="res.groups">
139+ <field name="name">Answer Survey Menu</field>
140+ </record>
141+
142+</data>
143+</openerp>
144
145=== added directory 'answer_survey/static'
146=== added directory 'answer_survey/static/src'
147=== added directory 'answer_survey/static/src/css'
148=== added file 'answer_survey/static/src/css/survey.css'
149--- answer_survey/static/src/css/survey.css 1970-01-01 00:00:00 +0000
150+++ answer_survey/static/src/css/survey.css 2013-10-22 03:10:23 +0000
151@@ -0,0 +1,25 @@
152+.icon-3x {
153+ padding:10px;
154+}
155+
156+.btn.btn-large.btn-primary {
157+ color:black;
158+ height:28px;
159+ width:140px;
160+ position:relative;
161+}
162+.oe_e span{
163+ height:32px;
164+ line-height:25px;
165+ text-align:center;
166+ left:60px;
167+ position:absolute;
168+ top:0;
169+ font-size: 34px;
170+}
171+button.answer_exit.btn.btn-large.btn-primary {
172+ color:black;
173+ background-color:red;
174+ width:10em;
175+ height:28px;
176+}
177
178=== added directory 'answer_survey/static/src/js'
179=== added directory 'answer_survey/static/src/xml'
180=== added directory 'answer_survey/view'
181=== added file 'answer_survey/view/answer_survey_menu.xml'
182--- answer_survey/view/answer_survey_menu.xml 1970-01-01 00:00:00 +0000
183+++ answer_survey/view/answer_survey_menu.xml 2013-10-22 03:10:23 +0000
184@@ -0,0 +1,11 @@
185+<?xml version="1.0" ?>
186+<openerp>
187+ <data>
188+
189+ <menuitem id="answer_survey_only_menu"
190+ groups='answer_survey.only_answer_menu'
191+ sequence='1'
192+ name='Answer Your Survies'
193+ action="survey.action_view_survey_name"/>
194+ </data>
195+</openerp>
196
197=== added directory 'answer_survey/wizard'
198=== added file 'answer_survey/wizard/__init__.py'
199--- answer_survey/wizard/__init__.py 1970-01-01 00:00:00 +0000
200+++ answer_survey/wizard/__init__.py 2013-10-22 03:10:23 +0000
201@@ -0,0 +1,25 @@
202+# -*- encoding: utf-8 -*-
203+##############################################################################
204+#
205+# OpenERP, Open Source Management Solution
206+# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
207+#
208+# This program is free software: you can redistribute it and/or modify
209+# it under the terms of the GNU Affero General Public License as
210+# published by the Free Software Foundation, either version 3 of the
211+# License, or (at your option) any later version.
212+#
213+# This program is distributed in the hope that it will be useful,
214+# but WITHOUT ANY WARRANTY; without even the implied warranty of
215+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
216+# GNU Affero General Public License for more details.
217+#
218+# You should have received a copy of the GNU Affero General Public License
219+# along with this program. If not, see <http://www.gnu.org/licenses/>.
220+#
221+##############################################################################
222+
223+import survey_send_invitation
224+import survey_selection
225+
226+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
227
228=== added file 'answer_survey/wizard/survey_answer.xml'
229--- answer_survey/wizard/survey_answer.xml 1970-01-01 00:00:00 +0000
230+++ answer_survey/wizard/survey_answer.xml 2013-10-22 03:10:23 +0000
231@@ -0,0 +1,16 @@
232+<?xml version="1.0" ?>
233+<openerp>
234+ <data>
235+
236+ <record id="survey.action_view_survey_name"
237+ model="ir.actions.act_window">
238+ <field name="name">Give Survey Answer</field>
239+ <field name="type">ir.actions.act_window</field>
240+ <field name="res_model">survey.name.wiz</field>
241+ <field name="view_type">form</field>
242+ <field name="view_mode">form</field>
243+ <field name="target">inline</field>
244+ </record>
245+
246+ </data>
247+</openerp>
248
249=== added file 'answer_survey/wizard/survey_selection.py'
250--- answer_survey/wizard/survey_selection.py 1970-01-01 00:00:00 +0000
251+++ answer_survey/wizard/survey_selection.py 2013-10-22 03:10:23 +0000
252@@ -0,0 +1,475 @@
253+# -*- encoding: utf-8 -*-
254+##############################################################################
255+#
256+# OpenERP, Open Source Management Solution
257+# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
258+#
259+# This program is free software: you can redistribute it and/or modify
260+# it under the terms of the GNU Affero General Public License as
261+# published by the Free Software Foundation, either version 3 of the
262+# License, or (at your option) any later version.
263+#
264+# This program is distributed in the hope that it will be useful,
265+# but WITHOUT ANY WARRANTY; without even the implied warranty of
266+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
267+# GNU Affero General Public License for more details.
268+#
269+# You should have received a copy of the GNU Affero General Public License
270+# along with this program. If not, see <http://www.gnu.org/licenses/>.
271+#
272+##############################################################################
273+
274+from lxml import etree
275+import os
276+from openerp import addons, netsvc, tools
277+from openerp.tools import to_xml
278+from openerp.tools.safe_eval import safe_eval
279+from openerp.osv import fields, osv
280+from openerp.tools.translate import _
281+
282+class survey_name_wiz(osv.TransientModel):
283+ _inherit = 'survey.name.wiz'
284+
285+ def action_next(self, cr, uid, ids, context=None):
286+ res = super(survey_name_wiz, self).action_next(cr, uid, ids, context)
287+
288+ res.update( {
289+ 'target': 'inline',
290+ })
291+ return res
292+
293+class survey_question_wiz(osv.TransientModel):
294+ _inherit = 'survey.question.wiz'
295+
296+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
297+ """
298+ Fields View Get method :- generate the new view and display the survey pages of selected survey.
299+ """
300+
301+ if context is None:
302+ context = {}
303+ result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
304+ view_type, {}, toolbar,submenu)
305+
306+ surv_name_wiz = self.pool.get('survey.name.wiz')
307+ survey_obj = self.pool.get('survey')
308+ page_obj = self.pool.get('survey.page')
309+ que_obj = self.pool.get('survey.question')
310+ ans_obj = self.pool.get('survey.answer')
311+ sur_response_obj = self.pool.get('survey.response')
312+ que_col_head = self.pool.get('survey.question.column.heading')
313+ user_obj = self.pool.get('res.users')
314+ mail_message = self.pool.get('mail.message')
315+
316+ if view_type in ['form']:
317+ wiz_id = 0
318+ sur_name_rec = None
319+ if 'sur_name_id' in context:
320+ sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
321+ elif 'survey_id' in context:
322+ res_data = {
323+ 'survey_id': context.get('survey_id', False),
324+ 'page_no': -1,
325+ 'page': 'next',
326+ 'transfer': 1,
327+ 'response': 0
328+ }
329+ wiz_id = surv_name_wiz.create(cr, uid, res_data)
330+ sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id, context=context)
331+ context.update({'sur_name_id' :wiz_id})
332+
333+ if context.has_key('active_id'):
334+ context.pop('active_id')
335+
336+ survey_id = context.get('survey_id', False)
337+ if not survey_id:
338+ # Try one more time to find it
339+ if sur_name_rec and sur_name_rec.survey_id:
340+ survey_id = sur_name_rec.survey_id.id
341+ else:
342+ # raise osv.except_osv(_('Error!'), _("Cannot locate survey for the question wizard!"))
343+ # If this function is called without a survey_id in
344+ # its context, it makes no sense to return any view.
345+ # Just return the default, empty view for this object,
346+ # in order to please random calls to this fn().
347+ return super(survey_question_wiz, self).\
348+ fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context,
349+ toolbar=toolbar, submenu=submenu)
350+ sur_rec = survey_obj.browse(cr, uid, survey_id, context=context)
351+ p_id = map(lambda x:x.id, sur_rec.page_ids)
352+ total_pages = len(p_id)
353+ pre_button = False
354+ readonly = 0
355+
356+ if context.get('response_id', False) \
357+ and int(context['response_id'][0]) > 0:
358+ readonly = 1
359+
360+ if not sur_name_rec.page_no + 1 :
361+ surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
362+
363+ sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
364+ page_number = int(sur_name_rec.page_no)
365+ if sur_name_read.transfer or not sur_name_rec.page_no + 1:
366+ surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
367+ flag = False
368+ fields = {}
369+ if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
370+ if total_pages > sur_name_rec.page_no + 1:
371+ if ((context.has_key('active') and not context.get('active', False)) \
372+ or not context.has_key('active')) and not sur_name_rec.page_no + 1:
373+ if sur_rec.state != "open" :
374+ raise osv.except_osv(_('Warning!'),_("You cannot answer because the survey is not open."))
375+ cr.execute('select count(id) from survey_history where user_id=%s\
376+ and survey_id=%s', (uid,survey_id))
377+ res = cr.fetchone()[0]
378+ user_limit = survey_obj.browse(cr, uid, survey_id)
379+ user_limit = user_limit.response_user
380+ if user_limit and res >= user_limit:
381+ raise osv.except_osv(_('Warning!'),_("You cannot answer this survey more than %s times.") % (user_limit))
382+
383+ 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:
384+ survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
385+
386+ p_id = p_id[sur_name_rec.page_no + 1]
387+ surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
388+ flag = True
389+ page_number += 1
390+ if sur_name_rec.page_no > - 1:
391+ pre_button = True
392+ else:
393+ flag = True
394+ else:
395+ if sur_name_rec.page_no != 0:
396+ p_id = p_id[sur_name_rec.page_no - 1]
397+ surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
398+ {'page_no' : sur_name_rec.page_no - 1})
399+ flag = True
400+ page_number -= 1
401+
402+ if sur_name_rec.page_no > 1:
403+ pre_button = True
404+ if flag:
405+ pag_rec = page_obj.browse(cr, uid, p_id, context=context)
406+ note = False
407+ question_ids = []
408+ if pag_rec:
409+ title = pag_rec.title
410+ note = pag_rec.note
411+ question_ids = pag_rec.question_ids
412+ else:
413+ title = sur_rec.title
414+ form = etree.Element('form', {'class':'bs3 bs3-form-bg bs3-footer','string': tools.ustr(title)})
415+ section = etree.SubElement(form, 'section', {'class': 'bgvauxoo'})
416+ xml_form = etree.SubElement(section, 'div', {'class': 'container'})
417+ if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
418+ context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
419+ xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
420+ etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
421+ etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
422+ etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
423+ etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
424+
425+ # FP Note
426+ xml_group = xml_form
427+
428+ if context.has_key('response_id') and context.get('response_id', False) \
429+ and int(context.get('response_id',0)[0]) > 0:
430+ # TODO: l10n, cleanup this code to make it readable. Or template?
431+ xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
432+ record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
433+ 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"})
434+ 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"})
435+ if context.get('response_no',0) > 0:
436+ etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
437+ if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
438+ 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)})
439+
440+ if wiz_id:
441+ fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
442+ etree.SubElement(xml_form, 'field', {'widget':'FieldCharBS3','invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0),'modifiers':'{"invisible":true}'})
443+
444+ if note:
445+ xml_group_note = etree.SubElement(xml_form, 'group', {'col': '1','colspan': '4'})
446+ for que_test in note.split('\n'):
447+ etree.SubElement(xml_group_note, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
448+ que_ids = question_ids
449+ qu_no = 0
450+
451+ for que in que_ids:
452+ qu_no += 1
453+ que_rec = que_obj.browse(cr, uid, que.id, context=context)
454+ descriptive_text = ""
455+ separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
456+ if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
457+ star = '*'
458+ else:
459+ star = ''
460+ if context.has_key('active') and context.get('active',False) and \
461+ context.has_key('edit'):
462+ etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
463+
464+ xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2',
465+ 'colspan': '2'})
466+ context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
467+ etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
468+ etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
469+ else:
470+ etree.SubElement(xml_form, 'newline')
471+ etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
472+
473+ ans_ids = que_rec.answer_choice_ids
474+ xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
475+
476+ if que_rec.type == 'multiple_choice_only_one_ans':
477+ selection = []
478+ for ans in ans_ids:
479+ selection.append((tools.ustr(ans.id), ans.answer))
480+ xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
481+ etree.SubElement(xml_group, 'field', {'nolabel':'True','class':'dropdown-menus','readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
482+ fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"}
483+
484+ elif que_rec.type == 'multiple_choice_multiple_ans':
485+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
486+ for ans in ans_ids:
487+ etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
488+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
489+
490+ elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
491+ if que_rec.comment_column:
492+ col = "4"
493+ colspan = "4"
494+ else:
495+ col = "2"
496+ colspan = "2"
497+ xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
498+ for row in ans_ids:
499+ etree.SubElement(xml_group, 'newline')
500+ 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))})
501+ selection = [('','')]
502+ for col in que_rec.column_heading_ids:
503+ selection.append((str(col.id), col.title))
504+ fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
505+ if que_rec.comment_column:
506+ fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
507+ etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
508+
509+ elif que_rec.type == 'matrix_of_choices_only_multi_ans':
510+ xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
511+ etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
512+ for col in que_rec.column_heading_ids:
513+ etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
514+ for row in ans_ids:
515+ etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
516+ for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
517+ etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
518+ fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
519+
520+ elif que_rec.type == 'matrix_of_drop_down_menus':
521+ xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
522+ etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
523+ for col in que_rec.column_heading_ids:
524+ etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
525+ for row in ans_ids:
526+ etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
527+ for col in que_rec.column_heading_ids:
528+ selection = []
529+ if col.menu_choice:
530+ for item in col.menu_choice.split('\n'):
531+ if item and not item.strip() == '': selection.append((item ,item))
532+ 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'})
533+ fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
534+
535+ elif que_rec.type == 'multiple_textboxes':
536+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
537+ type = "char"
538+ if que_rec.is_validation_require:
539+ if que_rec.validation_type in ['must_be_whole_number']:
540+ type = "integer"
541+ elif que_rec.validation_type in ['must_be_decimal_number']:
542+ type = "float"
543+ elif que_rec.validation_type in ['must_be_date']:
544+ type = "date"
545+ for ans in ans_ids:
546+ etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
547+ if type == "char" :
548+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
549+ else:
550+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
551+
552+ elif que_rec.type == 'numerical_textboxes':
553+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
554+ for ans in ans_ids:
555+ etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
556+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
557+
558+ elif que_rec.type == 'date':
559+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
560+ for ans in ans_ids:
561+ etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
562+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
563+
564+ elif que_rec.type == 'date_and_time':
565+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
566+ for ans in ans_ids:
567+ etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
568+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
569+
570+ elif que_rec.type == 'descriptive_text':
571+ if que_rec.descriptive_text:
572+ for que_test in que_rec.descriptive_text.split('\n'):
573+ etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
574+
575+ elif que_rec.type == 'single_textbox':
576+ etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
577+ fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
578+
579+ elif que_rec.type == 'comment':
580+ etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
581+ fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
582+
583+ elif que_rec.type == 'table':
584+ xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
585+ for col in que_rec.column_heading_ids:
586+ etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
587+ for row in range(0,que_rec.no_of_rows):
588+ for col in que_rec.column_heading_ids:
589+ 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"})
590+ fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
591+
592+ elif que_rec.type == 'multiple_textboxes_diff_type':
593+ xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
594+ for ans in ans_ids:
595+ if ans.type == "email" :
596+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
597+ 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"})
598+ else:
599+ etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
600+ if ans.type == "char" :
601+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
602+ elif ans.type in ['integer','float','date','datetime']:
603+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
604+ else:
605+ selection = []
606+ if ans.menu_choice:
607+ for item in ans.menu_choice.split('\n'):
608+ if item and not item.strip() == '': selection.append((item ,item))
609+ fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
610+
611+ 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:
612+ 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:
613+ etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
614+ fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
615+ if que_rec.comment_field_type == 'char':
616+ etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
617+ fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
618+ elif que_rec.comment_field_type == 'text':
619+ etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
620+ fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
621+ else:
622+ if que_rec.comment_field_type == 'char':
623+ etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
624+ etree.SubElement(xml_group, 'field', {'widget':'FieldCharBS3','readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
625+ fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
626+ elif que_rec.comment_field_type == 'text':
627+ etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
628+ etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
629+ fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
630+
631+ xml_footer = etree.SubElement(xml_form, 'footer', {'col': '8', 'colspan': '1', 'width':"100%"})
632+
633+ if pre_button:
634+ etree.SubElement(xml_footer, 'label', {'string': ""})
635+ etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':"e",'type':"object",'class':"answer_exit btn btn-primary btn-large oe_e"})
636+ but_string = "Next"
637+ if int(page_number) + 1 == total_pages:
638+ but_string = "Done"
639+ 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)):
640+ etree.SubElement(xml_footer, 'label', {'string': ""})
641+ etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
642+ elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
643+ etree.SubElement(xml_footer, 'label', {'string': ""})
644+ etree.SubElement(xml_footer, 'button', {'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
645+ elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
646+ etree.SubElement(xml_footer, 'label', {'string': ""})
647+ etree.SubElement(xml_footer, 'button', {'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context), 'class':"answer_exit btn btn-primary btn-large"})
648+ else:
649+ etree.SubElement(xml_footer, 'label', {'string': ""})
650+ 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)})
651+ etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':"c",'class':"answer_exit btn btn-primary btn-large oe_e"})
652+ etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
653+
654+ root = form.getroottree()
655+ result['arch'] = etree.tostring(root)
656+ result['fields'] = fields
657+ print 'rooooooooot',etree.tostring(root)
658+ print 'fields', fields
659+ result['context'] = context
660+ else:
661+ survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
662+ sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
663+
664+ # mark the survey request as done; call 'survey_req_done' on its actual model
665+ survey_req_obj = self.pool.get(context.get('active_model'))
666+ if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
667+ survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
668+
669+ if sur_rec.send_response:
670+ survey_data = survey_obj.browse(cr, uid, survey_id)
671+ response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
672+ report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
673+ attachments = {}
674+ pdf_filename = addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf"
675+ if os.path.exists(pdf_filename):
676+ file = open(pdf_filename)
677+ file_data = ""
678+ while 1:
679+ line = file.readline()
680+ file_data += line
681+ if not line:
682+ break
683+
684+ attachments[survey_data.title + ".pdf"] = file_data
685+ file.close()
686+ os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
687+ context.update({'response_id':response_id})
688+ user_email = user_obj.browse(cr, uid, uid, context).email
689+ resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
690+
691+ if user_email and resp_email:
692+ user_name = user_obj.browse(cr, uid, uid, context=context).name
693+ 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."
694+ vals = {'state': 'outgoing',
695+ 'subject': "Survey Answer Of " + user_name,
696+ 'body_html': '<pre>%s</pre>' % mail,
697+ 'email_to': [resp_email],
698+ 'email_from': user_email}
699+ if attachments:
700+ vals['attachment_ids'] = [(0,0,{'name': a_name,
701+ 'datas_fname': a_name,
702+ 'datas': str(a_content).encode('base64')})
703+ for a_name, a_content in attachments.items()]
704+ self.pool.get('mail.mail').create(cr, uid, vals, context=context)
705+
706+ xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
707+ xml_footer = etree.SubElement(xml_form, 'footer', {'col': '6', 'colspan': '4' ,'class': 'oe_survey_title_height'})
708+
709+ etree.SubElement(xml_form, 'separator', {'string': 'Survey Completed', 'colspan': "4"})
710+ etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
711+ etree.SubElement(xml_form, 'newline')
712+ etree.SubElement(xml_footer, 'button', {'special':"cancel",'string':"OK",'colspan':"2",'class':'oe_highlight'})
713+ root = xml_form.getroottree()
714+ result['arch'] = etree.tostring(root)
715+ result['fields'] = {}
716+ result['context'] = context
717+ return result
718+
719+
720+ def action_next(self, cr, uid, ids, context=None):
721+ res = super(survey_question_wiz, self).action_next(cr, uid, ids, context)
722+
723+ res.update( {
724+ 'target': 'inline',
725+ })
726+ return res
727+
728
729=== added file 'answer_survey/wizard/survey_send_invitation.py'
730--- answer_survey/wizard/survey_send_invitation.py 1970-01-01 00:00:00 +0000
731+++ answer_survey/wizard/survey_send_invitation.py 2013-10-22 03:10:23 +0000
732@@ -0,0 +1,166 @@
733+# -*- coding: utf-8 -*-
734+##############################################################################
735+#
736+# OpenERP, Open Source Management Solution
737+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>)
738+#
739+# This program is free software: you can redistribute it and/or modify
740+# it under the terms of the GNU Affero General Public License as
741+# published by the Free Software Foundation, either version 3 of the
742+# License, or (at your option) any later version
743+#
744+# This program is distributed in the hope that it will be useful,
745+# but WITHOUT ANY WARRANTY; without even the implied warranty of
746+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
747+# GNU Affero General Public License for more details
748+#
749+# You should have received a copy of the GNU Affero General Public License
750+# along with this program. If not, see <http://www.gnu.org/licenses/>
751+#
752+##############################################################################
753+
754+import time
755+from random import choice
756+import string
757+import os
758+import datetime
759+import socket
760+
761+from openerp import addons, netsvc, tools
762+from openerp.osv import fields, osv
763+from openerp.tools.translate import _
764+
765+
766+class survey_send_invitation(osv.TransientModel):
767+ _inherit = 'survey.send.invitation'
768+
769+ def action_send(self, cr, uid, ids, context=None):
770+ if context is None:
771+ context = {}
772+ record = self.read(cr, uid, ids, [],context=context)
773+ survey_ids = context.get('active_ids', [])
774+ record = record and record[0]
775+ partner_ids = record['partner_ids']
776+ user_ref= self.pool.get('res.users')
777+ survey_ref= self.pool.get('survey')
778+ mail_message = self.pool.get('mail.message')
779+
780+ model_data_obj = self.pool.get('ir.model.data')
781+ group_ids = []
782+ group_id = model_data_obj._get_id(cr, uid, 'base', 'group_survey_user')
783+ group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
784+ group_id = model_data_obj._get_id(cr, uid, 'answer_survey', 'only_answer_menu')
785+ group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
786+ group_id = model_data_obj._get_id(cr, uid, 'portal', 'group_portal')
787+ group_id and group_ids.append(model_data_obj.browse(cr, uid, group_id, context).res_id)
788+
789+ act_id = self.pool.get('ir.actions.act_window')
790+ act_id = act_id.search(cr, uid, [('res_model', '=' , 'survey.name.wiz'), \
791+ ('view_type', '=', 'form')])
792+ out = "login,password\n"
793+ skipped = 0
794+ existing = ""
795+ created = ""
796+ error = ""
797+ new_user = []
798+ attachments = {}
799+ current_sur = survey_ref.browse(cr, uid, context.get('active_id'), context=context)
800+ exist_user = current_sur.invited_user_ids
801+ if exist_user:
802+ for use in exist_user:
803+ new_user.append(use.id)
804+ for id in survey_ref.browse(cr, uid, survey_ids):
805+ report = self.create_report(cr, uid, [id.id], 'report.survey.form', id.title)
806+ file = open(addons.get_module_resource('survey', 'report') + id.title +".pdf")
807+ file_data = ""
808+ while 1:
809+ line = file.readline()
810+ file_data += line
811+ if not line:
812+ break
813+ file.close()
814+ attachments[id.title +".pdf"] = file_data
815+ os.remove(addons.get_module_resource('survey', 'report') + id.title +".pdf")
816+
817+ for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids):
818+ if not partner.email:
819+ skipped+= 1
820+ continue
821+ user = user_ref.search(cr, uid, [('login', "=", partner.email)])
822+ if user:
823+ if user[0] not in new_user:
824+ new_user.append(user[0])
825+ user = user_ref.browse(cr, uid, user[0])
826+ user_ref.write(cr, uid, user.id, {'survey_id':[[6, 0, survey_ids]]})
827+ mail = record['mail']%{'login':partner.email, 'passwd':user.password, \
828+ 'name' : partner.name}
829+ if record['send_mail_existing']:
830+ vals = {
831+ 'state': 'outgoing',
832+ 'subject': record['mail_subject_existing'],
833+ 'body_html': '<pre>%s</pre>' % mail,
834+ 'email_to': partner.email,
835+ 'email_from': record['mail_from'],
836+ }
837+ self.pool.get('mail.mail').create(cr, uid, vals, context=context)
838+ existing+= "- %s (Login: %s, Password: %s)\n" % (user.name, partner.email, \
839+ user.password)
840+ continue
841+
842+ passwd= self.genpasswd()
843+ out+= partner.email + ',' + passwd + '\n'
844+ mail= record['mail'] % {'login' : partner.email, 'passwd' : passwd, 'name' : partner.name}
845+ if record['send_mail']:
846+ vals = {
847+ 'state': 'outgoing',
848+ 'subject': record['mail_subject'],
849+ 'body_html': '<pre>%s</pre>' % mail,
850+ 'email_to': partner.email,
851+ 'email_from': record['mail_from'],
852+ }
853+ if attachments:
854+ vals['attachment_ids'] = [(0,0,{'name': a_name,
855+ 'datas_fname': a_name,
856+ 'datas': str(a_content).encode('base64')})
857+ for a_name, a_content in attachments.items()]
858+ ans = self.pool.get('mail.mail').create(cr, uid, vals, context=context)
859+ if ans:
860+ res_data = {'name': partner.name or _('Unknown'),
861+ 'login': partner.email,
862+ 'password': passwd,
863+ 'address_id': partner.id,
864+ 'groups_id': [[6, 0, group_ids]],
865+ 'action_id': act_id[0],
866+ 'survey_id': [[6, 0, survey_ids]]
867+ }
868+ user = user_ref.create(cr, uid, res_data)
869+ if user not in new_user:
870+ new_user.append(user)
871+ created+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
872+ partner.email, passwd)
873+ else:
874+ error+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
875+ partner.email, passwd)
876+
877+ new_vals = {}
878+ new_vals.update({'invited_user_ids':[[6,0,new_user]]})
879+ survey_ref.write(cr, uid, context.get('active_id'),new_vals)
880+ note= ""
881+ if created:
882+ note += 'Created users:\n%s\n\n' % (created)
883+ if existing:
884+ note +='Already existing users:\n%s\n\n' % (existing)
885+ if skipped:
886+ note += "%d contacts where ignored (an email address is missing).\n\n" % (skipped)
887+ if error:
888+ note += 'Email not send successfully:\n====================\n%s\n' % (error)
889+ context.update({'note' : note})
890+ return {
891+ 'view_type': 'form',
892+ "view_mode": 'form',
893+ 'res_model': 'survey.send.invitation.log',
894+ 'type': 'ir.actions.act_window',
895+ 'target': 'new',
896+ 'context': context
897+ }
898+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
899
900=== added directory 'user_wzd'
901=== added file 'user_wzd/__init__.py'
902--- user_wzd/__init__.py 1970-01-01 00:00:00 +0000
903+++ user_wzd/__init__.py 2013-10-22 03:10:23 +0000
904@@ -0,0 +1,2 @@
905+import model
906+import wizard
907\ No newline at end of file
908
909=== added file 'user_wzd/__openerp__.py'
910--- user_wzd/__openerp__.py 1970-01-01 00:00:00 +0000
911+++ user_wzd/__openerp__.py 2013-10-22 03:10:23 +0000
912@@ -0,0 +1,52 @@
913+# -*- encoding: utf-8 -*-
914+###########################################################################
915+# Module Writen to OpenERP, Open Source Management Solution
916+#
917+# Copyright (c) 2013 Vauxoo - http://www.vauxoo.com/
918+# All Rights Reserved.
919+# info Vauxoo (info@vauxoo.com)
920+############################################################################
921+# Coded by: Juan Funes (juan@vauxoo.com)
922+# Audited by: Vauxoo C.A.
923+############################################################################
924+#
925+# This program is free software: you can redistribute it and/or modify
926+# it under the terms of the GNU Affero General Public License as
927+# published by the Free Software Foundation, either version 3 of the
928+# License, or (at your option) any later version.
929+#
930+# This program is distributed in the hope that it will be useful,
931+# but WITHOUT ANY WARRANTY; without even the implied warranty of
932+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
933+# GNU Affero General Public License for more details.
934+#
935+# You should have received a copy of the GNU Affero General Public License
936+# along with this program. If not, see <http://www.gnu.org/licenses/>.
937+#
938+##############################################################################
939+
940+{
941+ "name": "user_wzd",
942+ "version": "1.0",
943+ "author": "Vauxoo",
944+ "category": "Generic Modules/Human Resources",
945+ "description": """
946+Add wizard for create employee from users
947+===============================================
948+
949+Module that adds a wizard in res.users model and generated employee from one or many users, only
950+and only if there is no other record of employee assigned to the user in question.
951+
952+ """,
953+ "website": "http://www.vauxoo.com/",
954+ "license": "AGPL-3",
955+ 'depends': ['hr'],
956+ "data": [
957+ "wizard/res_users_view.xml",
958+ ],
959+ "demo":[],
960+ "css": [],
961+ "test": [],
962+ "installable": True,
963+ "active": False,
964+}
965
966=== added directory 'user_wzd/i18n'
967=== added file 'user_wzd/i18n/es.po'
968--- user_wzd/i18n/es.po 1970-01-01 00:00:00 +0000
969+++ user_wzd/i18n/es.po 2013-10-22 03:10:23 +0000
970@@ -0,0 +1,62 @@
971+# Translation of OpenERP Server.
972+# This file contains the translation of the following modules:
973+# * user_wzd
974+#
975+msgid ""
976+msgstr ""
977+"Project-Id-Version: OpenERP Server 7.0\n"
978+"Report-Msgid-Bugs-To: \n"
979+"POT-Creation-Date: 2013-10-18 22:57+0000\n"
980+"PO-Revision-Date: 2013-10-18 22:57+0000\n"
981+"Last-Translator: <>\n"
982+"Language-Team: \n"
983+"MIME-Version: 1.0\n"
984+"Content-Type: text/plain; charset=UTF-8\n"
985+"Content-Transfer-Encoding: \n"
986+"Plural-Forms: \n"
987+
988+#. module: user_wzd
989+#: model:ir.actions.act_window,name:user_wzd.action_employee_from_user_wizard
990+msgid "Create Employee"
991+msgstr "Crear Empleado"
992+
993+#. module: user_wzd
994+#: field:employee.user.wizard,user_ids:0
995+msgid "Users"
996+msgstr "Usuarios"
997+
998+#. module: user_wzd
999+#: view:employee.user.wizard:0
1000+msgid "Create employee"
1001+msgstr "Crear Empleado"
1002+
1003+#. module: user_wzd
1004+#: model:ir.model,name:user_wzd.model_employee_user_wizard
1005+msgid "employee.user.wizard"
1006+msgstr "employee.user.wizard"
1007+
1008+#. module: user_wzd
1009+#: view:employee.user.wizard:0
1010+msgid "Select Users"
1011+msgstr "Selecciona Usuarios"
1012+
1013+#. module: user_wzd
1014+#: view:employee.user.wizard:0
1015+msgid "Cancel"
1016+msgstr "Cancelar"
1017+
1018+#. module: user_wzd
1019+#: view:employee.user.wizard:0
1020+msgid "Apply"
1021+msgstr "Aplicar"
1022+
1023+#. module: user_wzd
1024+#: view:employee.user.wizard:0
1025+msgid "Select a user, if you do not choose a user, were created employees for all users."
1026+msgstr "Seleccione un usuario, si usted no elige un usuario, se crearon los empleados de todos los usuarios."
1027+
1028+#. module: user_wzd
1029+#: view:employee.user.wizard:0
1030+msgid "or"
1031+msgstr "ó"
1032+
1033
1034=== added file 'user_wzd/i18n/es_MX.po'
1035--- user_wzd/i18n/es_MX.po 1970-01-01 00:00:00 +0000
1036+++ user_wzd/i18n/es_MX.po 2013-10-22 03:10:23 +0000
1037@@ -0,0 +1,62 @@
1038+# Translation of OpenERP Server.
1039+# This file contains the translation of the following modules:
1040+# * user_wzd
1041+#
1042+msgid ""
1043+msgstr ""
1044+"Project-Id-Version: OpenERP Server 7.0\n"
1045+"Report-Msgid-Bugs-To: \n"
1046+"POT-Creation-Date: 2013-10-18 22:57+0000\n"
1047+"PO-Revision-Date: 2013-10-18 22:57+0000\n"
1048+"Last-Translator: <>\n"
1049+"Language-Team: \n"
1050+"MIME-Version: 1.0\n"
1051+"Content-Type: text/plain; charset=UTF-8\n"
1052+"Content-Transfer-Encoding: \n"
1053+"Plural-Forms: \n"
1054+
1055+#. module: user_wzd
1056+#: model:ir.actions.act_window,name:user_wzd.action_employee_from_user_wizard
1057+msgid "Create Employee"
1058+msgstr "Crear Empleado"
1059+
1060+#. module: user_wzd
1061+#: field:employee.user.wizard,user_ids:0
1062+msgid "Users"
1063+msgstr "Usuarios"
1064+
1065+#. module: user_wzd
1066+#: view:employee.user.wizard:0
1067+msgid "Create employee"
1068+msgstr "Crear Empleado"
1069+
1070+#. module: user_wzd
1071+#: model:ir.model,name:user_wzd.model_employee_user_wizard
1072+msgid "employee.user.wizard"
1073+msgstr "employee.user.wizard"
1074+
1075+#. module: user_wzd
1076+#: view:employee.user.wizard:0
1077+msgid "Select Users"
1078+msgstr "Selecciona Usuarios"
1079+
1080+#. module: user_wzd
1081+#: view:employee.user.wizard:0
1082+msgid "Cancel"
1083+msgstr "Cancelar"
1084+
1085+#. module: user_wzd
1086+#: view:employee.user.wizard:0
1087+msgid "Apply"
1088+msgstr "Aplicar"
1089+
1090+#. module: user_wzd
1091+#: view:employee.user.wizard:0
1092+msgid "Select a user, if you do not choose a user, were created employees for all users."
1093+msgstr "Seleccione un usuario, si usted no elige un usuario, se crearon los empleados de todos los usuarios."
1094+
1095+#. module: user_wzd
1096+#: view:employee.user.wizard:0
1097+msgid "or"
1098+msgstr "ó"
1099+
1100
1101=== added directory 'user_wzd/model'
1102=== added file 'user_wzd/model/__init__.py'
1103--- user_wzd/model/__init__.py 1970-01-01 00:00:00 +0000
1104+++ user_wzd/model/__init__.py 2013-10-22 03:10:23 +0000
1105@@ -0,0 +1,1 @@
1106+
1107
1108=== added directory 'user_wzd/static'
1109=== added directory 'user_wzd/static/src'
1110=== added directory 'user_wzd/static/src/img'
1111=== added file 'user_wzd/static/src/img/icon.png'
1112Binary files user_wzd/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and user_wzd/static/src/img/icon.png 2013-10-22 03:10:23 +0000 differ
1113=== added file 'user_wzd/static/src/img/icon2.png'
1114Binary files user_wzd/static/src/img/icon2.png 1970-01-01 00:00:00 +0000 and user_wzd/static/src/img/icon2.png 2013-10-22 03:10:23 +0000 differ
1115=== added directory 'user_wzd/wizard'
1116=== added file 'user_wzd/wizard/__init__.py'
1117--- user_wzd/wizard/__init__.py 1970-01-01 00:00:00 +0000
1118+++ user_wzd/wizard/__init__.py 2013-10-22 03:10:23 +0000
1119@@ -0,0 +1,1 @@
1120+import res_users_wzd
1121
1122=== added file 'user_wzd/wizard/res_users_view.xml'
1123--- user_wzd/wizard/res_users_view.xml 1970-01-01 00:00:00 +0000
1124+++ user_wzd/wizard/res_users_view.xml 2013-10-22 03:10:23 +0000
1125@@ -0,0 +1,44 @@
1126+<openerp>
1127+ <data>
1128+ <record model="ir.ui.view" id="view_employee_from_user_wizard">
1129+ <field name="name">employee.from.user.form</field>
1130+ <field name="model">employee.user.wizard</field>
1131+ <field name="arch" type="xml">
1132+ <form string="Create employee" version="7.0">
1133+ <footer>
1134+ <button name="create_employee" type="object" string="Apply" class="oe_highlight"/>
1135+ or
1136+ <button string="Cancel" class="oe_link" special="cancel" />
1137+ </footer>
1138+ <separator colspan="4"/>
1139+ <p class="oe_grey">
1140+ Select a user, if you do not choose a user, were created employees for all users.
1141+ </p>
1142+ <group string="Select Users">
1143+ <field name="user_ids" colspan="4" nolabel="1"/>
1144+ </group>
1145+ </form>
1146+ </field>
1147+ </record>
1148+
1149+ <record id="action_employee_from_user_wizard" model="ir.actions.act_window">
1150+ <field name="name">Create employee</field>
1151+ <field name="type">ir.actions.act_window</field>
1152+ <field name="res_model">employee.user.wizard</field>
1153+ <field name="view_type">form</field>
1154+ <field name="view_mode">form</field>
1155+ <field name="view_id" ref="view_employee_from_user_wizard"/>
1156+ <field name="target">new</field>
1157+ </record>
1158+
1159+ <act_window name="Create Employee"
1160+ res_model="employee.user.wizard"
1161+ src_model="res.users"
1162+ view_mode="form"
1163+ target="new"
1164+ key2="client_action_multi"
1165+ id="action_employee_from_user_wizard"
1166+ />
1167+
1168+ </data>
1169+</openerp>
1170
1171=== added file 'user_wzd/wizard/res_users_wzd.py'
1172--- user_wzd/wizard/res_users_wzd.py 1970-01-01 00:00:00 +0000
1173+++ user_wzd/wizard/res_users_wzd.py 2013-10-22 03:10:23 +0000
1174@@ -0,0 +1,147 @@
1175+# -*- encoding: utf-8 -*-
1176+#
1177+# Module Writen to OpenERP, Open Source Management Solution
1178+#
1179+# Copyright (c) 2012 Vauxoo - http://www.vauxoo.com
1180+# All Rights Reserved.
1181+# info@vauxoo.com
1182+#
1183+# Coded by: Juan Carlos Funes(juan@vauxoo.com)
1184+#
1185+#
1186+# This program is free software: you can redistribute it and/or modify
1187+# it under the terms of the GNU Affero General Public License as
1188+# published by the Free Software Foundation, either version 3 of the
1189+# License, or (at your option) any later version.
1190+#
1191+# This program is distributed in the hope that it will be useful,
1192+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1193+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1194+# GNU Affero General Public License for more details.
1195+#
1196+# You should have received a copy of the GNU Affero General Public License
1197+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1198+#
1199+#
1200+
1201+from openerp.tools.translate import _
1202+from openerp.osv import fields, osv
1203+from openerp import pooler, tools
1204+
1205+
1206+class employee_user_wizard(osv.TransientModel):
1207+ _name = 'employee.user.wizard'
1208+
1209+ def default_get(self, cr, uid, fields, context=None):
1210+ if context is None:
1211+ context = {}
1212+
1213+ res = super(employee_user_wizard, self).default_get(cr, uid, fields, context=context)
1214+ user_ids = context.get('active_ids', False)
1215+ if user_ids:
1216+ all_ids = self.get_unconfigured_cmp(cr, uid, context)
1217+ user_ids = [i for i in user_ids if i in all_ids]
1218+ res.update({'user_ids': user_ids})
1219+
1220+
1221+
1222+ return res
1223+
1224+
1225+ _columns = {
1226+ 'user_ids': fields.many2many('res.users', 'res_users_wizard_rel', 'user_wizard_id', 'user_id', 'Users'),
1227+ }
1228+
1229+ _defaults = {
1230+ #'user_ids': _default_users
1231+ }
1232+
1233+ def get_unconfigured_cmp(self, cr, uid, context=None):
1234+ """ get the list of users that have not been configured yet """
1235+ if context is None:
1236+ context = {}
1237+ cmp_select = []
1238+ user_ids = self.pool.get('res.users').search(
1239+ cr, uid, [], context=context)
1240+ cr.execute("""SELECT users.id FROM res_users as users
1241+ JOIN resource_resource as resource
1242+ ON resource.user_id = users.id GROUP BY users.id""")
1243+ configured_cmp = [r[0] for r in cr.fetchall()]
1244+ return list(set(user_ids) - set(configured_cmp))
1245+
1246+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
1247+ if context is None:
1248+ context = {}
1249+ res = super(employee_user_wizard, self).fields_view_get(
1250+ cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
1251+ cmp_select = []
1252+ # display in the widget selection only the users that haven't been configured yet
1253+ unconfigured_cmp = self.get_unconfigured_cmp(cr, uid, context=context)
1254+ for field in res['fields']:
1255+ if field == 'user_ids':
1256+ res['fields'][field]['domain'] = [
1257+ ('id', 'in', unconfigured_cmp)]
1258+ res['fields'][field]['selection'] = [('', '')]
1259+ if unconfigured_cmp:
1260+ cmp_select = [(line.id, line.name)
1261+ for line in self.pool.get('res.users').browse(cr, uid, unconfigured_cmp)]
1262+ res['fields'][field]['selection'] = cmp_select
1263+ return res
1264+
1265+ def create_employee(self, cr, uid, ids, context=None):
1266+ if context is None:
1267+ context = {}
1268+ employee_list = []
1269+ ids = isinstance(ids, (int, long)) and [ids] or ids
1270+ employee_obj = self.pool.get('hr.employee')
1271+ resource_obj = self.pool.get('resource.resource')
1272+ users_obj = self.pool.get('res.users')
1273+ mod_obj = self.pool.get('ir.model.data')
1274+ act_obj = self.pool.get('ir.actions.act_window')
1275+ form = self.read(cr, uid, ids, context=context)
1276+ users_ids = form[0]['user_ids'] or self.get_unconfigured_cmp(cr, uid, context=context)
1277+ for user in users_obj.browse(cr, uid, users_ids, context):
1278+ vals_resource = {'name': user.name or False, 'user_id': user.id or False}
1279+ resource_id = resource_obj.create(cr, uid, vals_resource, context=context)
1280+ vals_employee = {'name_related': user.name or False,
1281+ 'resource_id': resource_id or False,
1282+ 'image': user.image or False,
1283+ 'company_id': user.company_id.id or False,
1284+ 'work_email': user.email or False}
1285+ employee_id = employee_obj.create(cr, uid, vals_employee, context=context)
1286+ employee_id = int(employee_id)
1287+ employee_list.append(employee_id)
1288+ if employee_list:
1289+ result = mod_obj.get_object_reference(cr, uid, 'hr', 'open_view_employee_list_my')
1290+ id = result and result[1] or False
1291+ result = act_obj.read(cr, uid, [id], context=context)[0]
1292+ #choose the view_mode accordingly
1293+ result['domain'] = "[('id','in',["+','.join(map(str, employee_list))+"])]"
1294+ result['res_id'] = employee_list and employee_list[0] or False
1295+ #choose the order
1296+ result['views'] = [(False, u'tree'), (False, u'kanban'), (False, u'form')]
1297+ return result
1298+ return True
1299+
1300+
1301+
1302+
1303+
1304+
1305+
1306+
1307+
1308+
1309+
1310+
1311+
1312+
1313+
1314+
1315+
1316+
1317+
1318+
1319+
1320+
1321+