[REF] Importing previous work by chm

bzr revid: rim@openerp.com-20131021090319-zbi93frwqpcvxkk9
This commit is contained in:
Richard Mathot (OpenERP) 2013-10-21 11:03:19 +02:00
parent 43a09310cb
commit 31c582874d
69 changed files with 2356 additions and 67340 deletions

View File

@ -33,32 +33,33 @@ question may have multiple answers. Different users may give different answers o
question and according to that survey is done. Partners are also sent mails with
user name and password for the invitation of the survey.
""",
'summary': 'Create survey, collect answers and print statistics',
'author': 'OpenERP SA',
'depends': ['mail'],
'website': 'http://www.openerp.com',
'depends': ['email_template', 'mail'],
'data': [
'survey_report.xml',
'survey_data.xml',
'wizard/survey_selection.xml',
'wizard/survey_answer.xml',
'security/survey_security.xml',
'security/ir.model.access.csv',
'survey_view.xml',
'wizard/survey_answer.xml',
'wizard/survey_print_statistics.xml',
'wizard/survey_print_answer.xml',
'wizard/survey_browse_answer.xml',
'wizard/survey_print.xml',
'wizard/survey_send_invitation.xml'
'wizard/survey_email_compose_message.xml',
],
'demo': ['survey_demo.xml'],
'test': [
'test/draft2open2close_survey.yml',
'test/draft2open2close_request.yml',
'test/survey_question_type.yml',
'test/survey_report.yml',
'test/survey_response.py',
],
'installable': True,
'auto_install': False,
'application': True,
'sequence': 10,
'images': ['images/survey_answers.jpeg', 'images/survey_pages.jpeg', 'images/surveys.jpeg'],
'css': ['static/src/css/survey.css','static/css/survey.css'],
'css': ['static/src/css/survey.css'],
'js': ['static/src/js/survey.js'],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -301,12 +301,12 @@ class survey_analysis(report_rml):
rating_weight_sum = 0
for mat_col in range(1, len(matrix_ans)):
cr.execute("select count(sra.answer_id) from survey_response_line sr, survey_response_answer sra\
where sr.id = sra.response_id and sra.answer_id = %s and sra.column_id ='%s'", (ans.id,matrix_ans[mat_col][0]))
where sr.id = sra.response_line_id and sra.answer_id = %s and sra.column_id ='%s'", (ans.id,matrix_ans[mat_col][0]))
tot_res = cr.fetchone()[0]
cr.execute("select count(sra.answer_id),sqc.rating_weight from survey_response_line sr, survey_response_answer sra ,\
survey_question_column_heading sqc where sr.id = sra.response_id and \
survey_question_column_heading sqc where sr.id = sra.response_line_id and \
sqc.question_id = sr.question_id and sra.answer_id = %s and sqc.title ='%s'\
+ group by sra.answer_id,sqc.rating_weight", (ans.id,matrix_ans[mat_col][1]))
group by sra.answer_id,sqc.rating_weight", (ans.id,matrix_ans[mat_col][1]))
col_weight = cr.fetchone()
if not col_weight:
@ -332,54 +332,6 @@ class survey_analysis(report_rml):
<td><para style="answer_right">""" + tools.ustr(res_count) + """</para></td></tr>"""
rml += """</blockTable>"""
elif que.type in['matrix_of_drop_down_menus']:
for column in que.column_heading_ids:
rml += """<blockTable colWidths="500" style="Table1"><tr>
<td><para style="answer">""" + to_xml(tools.ustr(column.title)) + """</para></td></tr></blockTable>"""
menu_choices = column.menu_choice.split('\n')
cols_widhts = []
cols_widhts.append(200)
for col in range(0, len(menu_choices) + 1):
cols_widhts.append(float(300 / (len(menu_choices) + 1)))
colWidths = ",".join(map(tools.ustr, cols_widhts))
rml += """<blockTable colWidths=" """ + colWidths + """ " style="Table1"><tr>
<td><para style="response"></para></td>"""
for menu in menu_choices:
rml += """<td><para style="response">""" + to_xml(tools.ustr(menu)) + """</para></td>"""
rml += """<td><para style="response-bold">Answer Count</para></td></tr>"""
cr.execute("select count(id), sra.answer_id from survey_response_answer sra \
where sra.column_id='%s' group by sra.answer_id ", (column.id,))
res_count = cr.dictfetchall()
cr.execute("select count(sra.id),sra.value_choice, sra.answer_id, sra.column_id from survey_response_answer sra \
where sra.column_id='%s' group by sra.value_choice ,sra.answer_id, sra.column_id", (column.id,))
calc_percantage = cr.dictfetchall()
for ans in que.answer_choice_ids:
rml += """<tr><td><para style="answer_right">""" + to_xml(tools.ustr(ans.answer)) + """</para></td>"""
for mat_col in range(0, len(menu_choices)):
calc = 0
response = 0
for res in res_count:
if res['answer_id'] == ans.id: response = res['count']
for per in calc_percantage:
if ans.id == per['answer_id'] and menu_choices[mat_col] == per['value_choice']:
calc = per['count']
percantage = 0.00
if calc and response:
percantage = round((float(calc)* 100) / response,2)
if calc:
rml += """<td><para style="answer_bold">""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)</para></td>"""
else:
rml += """<td><para style="answer">""" +tools.ustr(percantage)+"% (" + tools.ustr(calc) + """)</para></td>"""
response = 0
for res in res_count:
if res['answer_id'] == ans.id: response = res['count']
rml += """<td><para style="answer_right">""" + tools.ustr(response) + """</para></td></tr>"""
rml += """</blockTable>"""
elif que.type in['numerical_textboxes']:
rml += """<blockTable colWidths="240.0,20,100.0,70,70.0" style="Table1">
<tr>
@ -414,8 +366,8 @@ class survey_analysis(report_rml):
</tr>
<tr>
<td><para style="Standard1"></para></td>
<td><para style="Standard1">Skipped Question</para></td>
<td><para style="Standard1">""" + tools.ustr(survey.tot_start_survey - que.tot_resp) + """</para></td>
<td><para style="Standard1">Skipped Questions</para></td>
<td><para style="Standard1">""" + tools.ustr(que.tot_resp - survey.tot_start_survey) + """</para></td>
</tr>
</blockTable>"""
rml += """</story>"""

View File

@ -27,7 +27,6 @@ from openerp import tools
from openerp.report import report_sxw
from openerp.report.interface import report_rml
from openerp.tools import to_xml
from openerp.tools.translate import _
class survey_browse_response(report_rml):
def create(self, cr, uid, ids, datas, context):
@ -70,7 +69,7 @@ class survey_browse_response(report_rml):
rml +="""
<fill color="gray"/>
<setFont name="Helvetica" size="10"/>
<drawRightString x='"""+tools.ustr(float(_pageSize[0].replace('cm','')) - float(1.00))+'cm'+"""' y="0.6cm">"""+_('Page : ')+"""<pageNumber/> </drawRightString>"""
<drawRightString x='"""+tools.ustr(float(_pageSize[0].replace('cm','')) - float(1.00))+'cm'+"""' y="0.6cm">Page : <pageNumber/> </drawRightString>"""
rml +="""</pageGraphics>
</pageTemplate>
</template>
@ -210,29 +209,29 @@ class survey_browse_response(report_rml):
resp_create = tools.ustr(time.strftime('%d-%m-%Y %I:%M:%S %p', time.strptime(response.date_create.split('.')[0], '%Y-%m-%d %H:%M:%S')))
rml += """<blockTable colWidths='""" + colwidth + """' style="Table_heading">
<tr>
<td><para style="terp_default_9_Bold">""" + _('Print Date : ') + """</para></td>
<td><para style="terp_default_9_Bold">Print Date : </para></td>
<td><para style="terp_default_9">""" + to_xml(rml_obj.formatLang(time.strftime("%Y-%m-%d %H:%M:%S"),date_time=True)) + """</para></td>
<td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9_Bold">""" +_('Answered by : ') + """</para></td>
<td><para style="terp_default_9">""" + to_xml(response.user_id.login or '') + """</para></td>
<td><para style="terp_default_9_Bold">Answered by : </para></td>
<td><para style="terp_default_9">""" + to_xml(response.partner_id.name or '') + """</para></td>
</tr>
<tr>
<td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9_Bold">""" +_('Answer Date : ') + """</para></td>
<td><para style="terp_default_9_Bold">Answer Date : </para></td>
<td><para style="terp_default_9">""" + to_xml(resp_create) + """</para></td>
</tr>
</blockTable><para style="P2"></para>"""
status = _("Not Finished")
if response.state == "done": status = _("Finished")
status = "Not Finished"
if response.state == "done": status = "Finished"
colwidth = str(tbl_width - 7) + "cm,"
colwidth += "7cm"
rml += """<blockTable colWidths='""" + str(colwidth) + """' style="title_tbl">
<tr>
<td><para style="title">""" + to_xml(tools.ustr(survey.title)) + """</para><para style="P2"><font></font></para></td>
<td><para style="descriptive_text_heading">"""+_('Status :- ')+ to_xml(tools.ustr(status)) + """</para><para style="P2"><font></font></para></td>
<td><para style="descriptive_text_heading">Status :- """ + to_xml(tools.ustr(status)) + """</para><para style="P2"><font></font></para></td>
</tr>
</blockTable>"""
@ -243,7 +242,7 @@ class survey_browse_response(report_rml):
for page in survey.page_ids:
rml += """<blockTable colWidths='""" + str(_tbl_widths) + """' style="page_tbl">
<tr><td><para style="page">"""+_('Page :- ') + to_xml(tools.ustr(page.title or '')) + """</para></td></tr>
<tr><td><para style="page">Page :- """ + to_xml(tools.ustr(page.title or '')) + """</para></td></tr>
</blockTable>"""
if page.note:
rml += """<para style="P2"></para>
@ -303,7 +302,7 @@ class survey_browse_response(report_rml):
else:
rml +="""<blockTable colWidths='""" + str(_tbl_widths) + """' style="simple_table">
<tr><td> <para style="response">"""+ _('No Answer') + """</para></td> </tr>
<tr><td> <para style="response">No Answer</para></td> </tr>
</blockTable>"""
elif que.type in ['multiple_choice_only_one_ans','multiple_choice_multiple_ans']:
@ -427,7 +426,7 @@ class survey_browse_response(report_rml):
<tr> <td> <para style="response">No Answer</para></td> </tr>
</blockTable>"""
elif que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans', 'rating_scale', 'matrix_of_drop_down_menus']:
elif que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans', 'rating_scale']:
if len(answer) and answer[0].state == "done":
if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale'] and que.comment_column:
pass
@ -482,9 +481,7 @@ class survey_browse_response(report_rml):
for res_ans in answer[0].response_answer_ids:
if res_ans.answer_id.id == ans.id and res_ans.column_id.id == matrix_ans[mat_col][0]:
comment_value = to_xml(tools.ustr(res_ans.comment_field))
if que.type in ['matrix_of_drop_down_menus']:
value = """<para style="response">""" + to_xml(tools.ustr(res_ans.value_choice)) + """</para>"""
elif que.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
value = """<illustration><fill color="white"/>
<circle x="0.3cm" y="-0.18cm" radius="0.22 cm" fill="yes" stroke="yes"/>
<fill color="gray"/>
@ -499,9 +496,7 @@ class survey_browse_response(report_rml):
</illustration>"""
break
else:
if que.type in ['matrix_of_drop_down_menus']:
value = """"""
elif que.type in ['matrix_of_choices_only_one_ans','rating_scale']:
if que.type in ['matrix_of_choices_only_one_ans','rating_scale']:
value = """<illustration><fill color="white"/>
<circle x="0.3cm" y="-0.18cm" radius="0.22 cm" fill="yes" stroke="yes" round="0.1cm"/>
</illustration>"""

View File

@ -24,6 +24,10 @@ import openerp
from openerp import tools
from openerp.report.interface import report_rml
from openerp.tools import to_xml
import lxml
from lxml.html.clean import Cleaner
cleaner = Cleaner(style=True, links=False, add_nofollow=True, page_structure=True, safe_attrs_only=True)
class survey_form(report_rml):
def create(self, cr, uid, ids, datas, context):
@ -180,18 +184,24 @@ class survey_form(report_rml):
<tr><td><para style="question">""" + to_xml(tools.ustr(que.question)) + """</para></td></tr>
</blockTable>
<para style="P2"><font></font></para>"""
if que.type in ['descriptive_text']:
cols_widhts.append(float(_tbl_widths.replace('cm','')))
colWidths = "cm,".join(map(tools.ustr, cols_widhts))
colWidths = colWidths + 'cm'
if que.descriptive_text:
style = (que.type in ['descriptive_text']) and ' style="ans_tbl" ' or ""
descriptive_text = lxml.etree.tostring(
cleaner.clean_html(
lxml.html.fromstring(que.descriptive_text)))
rml += """
<blockTable colWidths=" """ + colWidths + """ " style="ans_tbl">
<blockTable colWidths=" """ + _tbl_widths + """ " """ + style + """>
<tr>
<td>
<para style="descriptive_text">""" + to_xml(tools.ustr(que.descriptive_text)) + """</para>
<para style="descriptive_text">""" + descriptive_text + """</para>
</td>
</tr>
</blockTable>"""
if que.type not in ['descriptive_text']:
rml += """<para style="P2"><font></font></para>"""
if que.type in ['descriptive_text']:
continue
elif que.type in ['multiple_choice_multiple_ans','multiple_choice_only_one_ans']:
answer = []
@ -245,7 +255,7 @@ class survey_form(report_rml):
rml += """
</tr></blockTable>"""
elif que.type in ['matrix_of_choices_only_one_ans','rating_scale','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus']:
elif que.type in ['matrix_of_choices_only_one_ans','rating_scale','matrix_of_choices_only_multi_ans']:
if len(que.column_heading_ids):
cols_widhts.append(float(_tbl_widths.replace('cm',''))/float(2.0))
for col in que.column_heading_ids:
@ -272,7 +282,7 @@ class survey_form(report_rml):
if col.title not in matrix_ans:
matrix_ans.append(col.title)
if que.comment_column:
matrix_ans.append(to_xml(tools.ustr(que.column_name)))
matrix_ans.append(tools.ustr(que.column_name))
rml+="""<blockTable colWidths=" """ + colWidths + """ " style="ans_tbl"><tr>"""
for mat_col in matrix_ans:
@ -291,10 +301,7 @@ class survey_form(report_rml):
rec_width = float((sum-tmp)*10+100)
value = ""
if que.type in ['matrix_of_drop_down_menus']:
value = """ <fill color="white"/>
<rect x="-0.1cm" y="-0.45cm" width='""" + tools.ustr(cols_widhts[-1] - 0.5) +"cm" + """' height="0.5cm" fill="yes" stroke="yes" round="0.1cm"/>"""
elif que.type in ['matrix_of_choices_only_one_ans','rating_scale']:
if que.type in ['matrix_of_choices_only_one_ans','rating_scale']:
value = """ <fill color="white"/>
<circle x="0.35cm" y="-0.18cm" radius="0.25 cm" fill="yes" stroke="yes"/>"""
else:
@ -331,12 +338,18 @@ class survey_form(report_rml):
elif que.type in ['comment']:
cols_widhts.append(float(_tbl_widths.replace('cm','')))
colWidths = "cm,".join(map(tools.ustr, cols_widhts))
rml += """<blockTable colWidths=" """ + colWidths + """cm " style="ans_tbl">
inner_Widths = []
for width in cols_widhts:
inner_Widths.append(width - 0.6)
colWidths = "cm,".join(map(tools.ustr, cols_widhts)) + 'cm'
InnerWidths = "cm,".join(map(tools.ustr, inner_Widths)) + 'cm'
rml += """<blockTable colWidths=" """ + colWidths + """ " style="ans_tbl">
<tr>
<td><para style="comment"><font color="white"> </font></para>
<illustration>
<rect x="0.1cm" y="0.3cm" width='""" + tools.ustr(str(float(colWidths) - 0.6) +'cm') + """' height="1.5cm" fill="no" stroke="yes"/>
<rect x="0.1cm" y="0.3cm" width='""" + InnerWidths + """' height="1.5cm" fill="no" stroke="yes"/>
</illustration>
</td>
</tr>
@ -344,13 +357,19 @@ class survey_form(report_rml):
elif que.type in ['single_textbox']:
cols_widhts.append(float(_tbl_widths.replace('cm','')))
colWidths = "cm,".join(map(tools.ustr, cols_widhts))
inner_Widths = []
for width in cols_widhts:
inner_Widths.append(width - 0.7)
colWidths = "cm,".join(map(tools.ustr, cols_widhts)) + 'cm'
InnerWidths = "cm,".join(map(tools.ustr, inner_Widths)) + 'cm'
rml += """<para style="P2"><font color="white"> </font></para>
<blockTable colWidths=" """ + colWidths + """cm " style="ans_tbl">
<blockTable colWidths=" """ + colWidths + """ " style="ans_tbl">
<tr>
<td>
<illustration>
<rect x="0.2cm" y="0.3cm" width='""" + tools.ustr(str(float(colWidths) - 0.7) +'cm') + """' height="0.6cm" fill="no" stroke="yes"/>
<rect x="0.2cm" y="0.3cm" width='""" + InnerWidths + """' height="0.6cm" fill="no" stroke="yes"/>
</illustration>
</td>
</tr>

View File

@ -1,24 +1,11 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_survey_type_manager,survey.type.manager,model_survey_type,base.group_tool_manager,1,1,1,1
access_survey_request_manager,survey.request manager,model_survey_request,base.group_tool_manager,1,1,1,1
access_survey_tbl_column_heading_manager,survey.tbl.column.heading manager,model_survey_tbl_column_heading,base.group_tool_manager,1,1,1,1
access_survey_res_partner_user,survey.res.partner.user,base.model_res_partner,base.group_tool_user,1,1,1,1
access_survey_user,survey.user,model_survey,base.group_tool_user,1,1,1,1
access_survey_page_user,survey.page user,model_survey_page,base.group_tool_user,1,1,1,1
access_survey_question_user,survey.question user,model_survey_question,base.group_tool_user,1,1,1,1
access_survey_answer_user,survey.answer user,model_survey_answer,base.group_tool_user,1,1,1,1
access_survey_response_user,survey.response user,model_survey_response,base.group_tool_user,1,1,1,1
access_survey_response_answer_user,survey.response.answer user,model_survey_response_answer,base.group_tool_user,1,1,1,1
access_survey_history_user,survey.history.user,model_survey_history,base.group_tool_user,1,1,1,1
access_survey_response_line_user,survey.response.line user,model_survey_response_line,base.group_tool_user,1,1,1,1
access_survey_res_partner_user,survey.res.partner.user,base.model_res_partner,base.group_tool_user,1,1,1,1
access_survey_survey_user,survey.survey.user,model_survey,base.group_survey_user,1,1,1,1
access_survey_page_survey_user,survey.page.survey.user,model_survey_page,base.group_survey_user,1,1,1,1
access_survey_question_survey_user,survey.question.survey.user,model_survey_question,base.group_survey_user,1,1,1,1
access_survey_answer_survey_user,survey.answer.survey.user,model_survey_answer,base.group_survey_user,1,1,1,1
access_survey_response_survey_user,survey.response.survey.user,model_survey_response,base.group_survey_user,1,1,1,1
access_survey_response_answer_survey_user,survey.response.answer.survey.user,model_survey_response_answer,base.group_survey_user,1,1,1,1
access_survey_history_survey_user,survey.history.survey.user,model_survey_history,base.group_survey_user,1,1,1,1
access_survey_response_line_survey_user,survey.response.line.survey.user,model_survey_response_line,base.group_survey_user,1,1,1,1
access_survey_question_column_heading_survey_user,survey.question.column.heading.survey.user,model_survey_question_column_heading,base.group_survey_user,1,0,0,0
access_survey_question_column_heading_user,survey.question.column.heading user,model_survey_question_column_heading,base.group_tool_user,1,1,1,1
access_survey_type_manager,survey.type.manager,model_survey_type,base.group_survey_manager,1,1,1,1
access_survey_question_column_heading_manager,survey.question.column.heading user,model_survey_question_column_heading,base.group_survey_manager,1,1,1,1
access_survey_manager,survey.manager,model_survey,base.group_survey_manager,1,1,1,1
access_survey_user,survey.user,model_survey,base.group_survey_user,1,0,0,0
access_survey_page_manager,survey.page user,model_survey_page,base.group_survey_manager,1,1,1,1
access_survey_question_manager,survey.question user,model_survey_question,base.group_survey_manager,1,1,1,1
access_survey_answer_manager,survey.answer user,model_survey_answer,base.group_survey_manager,1,1,1,1
access_survey_response_manager,survey.response user,model_survey_response,base.group_survey_manager,1,1,1,1
access_survey_response_answer_manager,survey.response.answer user,model_survey_response_answer,base.group_survey_manager,1,1,1,1
access_survey_response_line_manager,survey.response.line user,model_survey_response_line,base.group_survey_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_survey_type_manager survey.type.manager model_survey_type base.group_tool_manager base.group_survey_manager 1 1 1 1
3 access_survey_request_manager access_survey_question_column_heading_manager survey.request manager survey.question.column.heading user model_survey_request model_survey_question_column_heading base.group_tool_manager base.group_survey_manager 1 1 1 1
4 access_survey_tbl_column_heading_manager access_survey_manager survey.tbl.column.heading manager survey.manager model_survey_tbl_column_heading model_survey base.group_tool_manager base.group_survey_manager 1 1 1 1
5 access_survey_res_partner_user access_survey_user survey.res.partner.user survey.user base.model_res_partner model_survey base.group_tool_user base.group_survey_user 1 1 0 1 0 1 0
6 access_survey_user access_survey_page_manager survey.user survey.page user model_survey model_survey_page base.group_tool_user base.group_survey_manager 1 1 1 1
7 access_survey_page_user access_survey_question_manager survey.page user survey.question user model_survey_page model_survey_question base.group_tool_user base.group_survey_manager 1 1 1 1
8 access_survey_question_user access_survey_answer_manager survey.question user survey.answer user model_survey_question model_survey_answer base.group_tool_user base.group_survey_manager 1 1 1 1
9 access_survey_answer_user access_survey_response_manager survey.answer user survey.response user model_survey_answer model_survey_response base.group_tool_user base.group_survey_manager 1 1 1 1
10 access_survey_response_user access_survey_response_answer_manager survey.response user survey.response.answer user model_survey_response model_survey_response_answer base.group_tool_user base.group_survey_manager 1 1 1 1
11 access_survey_response_answer_user access_survey_response_line_manager survey.response.answer user survey.response.line user model_survey_response_answer model_survey_response_line base.group_tool_user base.group_survey_manager 1 1 1 1
access_survey_history_user survey.history.user model_survey_history base.group_tool_user 1 1 1 1
access_survey_response_line_user survey.response.line user model_survey_response_line base.group_tool_user 1 1 1 1
access_survey_res_partner_user survey.res.partner.user base.model_res_partner base.group_tool_user 1 1 1 1
access_survey_survey_user survey.survey.user model_survey base.group_survey_user 1 1 1 1
access_survey_page_survey_user survey.page.survey.user model_survey_page base.group_survey_user 1 1 1 1
access_survey_question_survey_user survey.question.survey.user model_survey_question base.group_survey_user 1 1 1 1
access_survey_answer_survey_user survey.answer.survey.user model_survey_answer base.group_survey_user 1 1 1 1
access_survey_response_survey_user survey.response.survey.user model_survey_response base.group_survey_user 1 1 1 1
access_survey_response_answer_survey_user survey.response.answer.survey.user model_survey_response_answer base.group_survey_user 1 1 1 1
access_survey_history_survey_user survey.history.survey.user model_survey_history base.group_survey_user 1 1 1 1
access_survey_response_line_survey_user survey.response.line.survey.user model_survey_response_line base.group_survey_user 1 1 1 1
access_survey_question_column_heading_survey_user survey.question.column.heading.survey.user model_survey_question_column_heading base.group_survey_user 1 0 0 0
access_survey_question_column_heading_user survey.question.column.heading user model_survey_question_column_heading base.group_tool_user 1 1 1 1

View File

@ -1,19 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<record model="res.groups" id="base.group_tool_user">
<field name="name">User</field>
<field name="category_id" ref="base.module_category_tools"/>
</record>
<record model="res.groups" id="base.group_tool_manager">
<field name="name">Manager</field>
<field name="category_id" ref="base.module_category_tools"/>
<field name="implied_ids" eval="[(4, ref('base.group_tool_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<data>
<record model="res.groups" id="base.group_survey_user">
<field name="name">Survey / User</field>
<field name="name">User</field>
<field name="category_id" ref="base.module_category_survey"/>
</record>
<record model="res.groups" id="base.group_survey_manager">
<field name="name">Manager</field>
<field name="category_id" ref="base.module_category_survey"/>
<field name="implied_ids" eval="[(4, ref('base.group_survey_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="survey_rule" model="ir.rule">
<field name="name">Survey</field>
<field ref="survey.model_survey" name="model_id"/>
<field name="domain_force">[('state', '=', 'open'), ('visible_to_user', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_survey_user'))]"/>
<field eval="0" name="perm_unlink"/>
<field eval="0" name="perm_write"/>
<field eval="1" name="perm_read"/>
<field eval="0" name="perm_create"/>
</record>
<record id="survey_rule_manager" model="ir.rule">
<field name="name">Survey</field>
<field ref="survey.model_survey" name="model_id"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('base.group_survey_manager'))]"/>
<field eval="1" name="perm_unlink"/>
<field eval="1" name="perm_write"/>
<field eval="1" name="perm_read"/>
<field eval="1" name="perm_create"/>
</record>
</data>
</openerp>

View File

@ -6,6 +6,97 @@
}
.openerp .oe_kanban_survey {
width: 200px;
width: 240px;
}
.openerp .oe_kanban_survey .oe_kanban_survey_list{
width: 100%;
}
.openerp .oe_kanban_survey .oe_kanban_status,
.openerp .oe_kanban_survey .oe_kanban_status_green,
.openerp .oe_kanban_survey .oe_kanban_status_darkgreen,
.openerp .oe_kanban_survey .oe_kanban_status_red {
display: block;
height: 10px;
width: 10px;
background-color: #dddddd;
border-radius: 5px;
margin-top: 3px;
}
.openerp .oe_kanban_survey .oe_kanban_status_green {
background-color: green;
}
.openerp .oe_kanban_survey .oe_kanban_status_darkgreen {
background-color: darkgreen;
}
.openerp .oe_kanban_survey .oe_kanban_status_red {
background-color: red;
}
.openerp .oe_kanban_survey .oe_inactive {
color: #aaaaaa;
}
.openerp .oe_survey_date_deadline {
white-space: nowrap;
height: 25px;
overflow: hidden;
line-height: 22px;
position: relative;
right: 0px;
top: -6px;
}
.openerp .oe_survey_email_public .oe_survey_url {
margin: 10px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
.openerp .oe_survey_email_public .oe_survey_url_label {
margin: 20px 10px 0px 10px;
font-weight: bold;
}
.openerp .oe_survey_email_public_choises {
margin: 20px 10px 0px 10px;
font-weight: bold;
}
.openerp .oe_survey_button {
border-radius: 4px;
padding: 3px 8px 4px 8px;
border: 1px solid #000;
border-width: 1px 1px 0 0;
text-shadow: none;
text-decoration: none !important;
}
.openerp .oe_survey_button, .openerp .oe_form .oe_survey button.oe_highlight {
color: #fff !important;
background-color: #c02c2c;
background-image: -webkit-gradient(linear, left top, left bottom, from(#df3f3f), to(#a21a1a));
background-image: -webkit-linear-gradient(top, #df3f3f, #a21a1a);
background-image: -moz-linear-gradient(top, #df3f3f, #a21a1a);
background-image: -ms-linear-gradient(top, #df3f3f, #a21a1a);
background-image: -o-linear-gradient(top, #df3f3f, #a21a1a);
background-image: linear-gradient(to bottom, #df3f3f, #a21a1a);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
}
.openerp .oe_form .oe_survey_answer .oe_form_sheet label {
max-width: 280px;
white-space: normal;
font-weight: bold;
padding-right: 8px;
}
.openerp .oe_form .oe_survey_answer .oe_form_sheet .oe_survey_matrix_of_choices_only_one_ans label,
.openerp .oe_form .oe_survey_answer .oe_form_sheet .oe_survey_multiple_choice_multiple_ans label {
min-width: 240px;
}
.openerp .oe_popup_form .oe_form_sheet.oe_survey {
padding-top: 0;
}
.openerp .oe_survey_fill {
display: none;
}

View File

@ -0,0 +1,11 @@
openerp.survey = function(openerp) {
openerp.web_kanban.KanbanRecord.include({
on_card_clicked: function(e) {
if (this.view.dataset.model === 'survey') {
this.$('.oe_survey_fill a:first').click();
} else {
this._super.apply(this, arguments);
}
},
});
};

View File

@ -20,81 +20,113 @@
##############################################################################
import copy
from urllib import urlencode
from urlparse import urljoin
from datetime import datetime
from dateutil.relativedelta import relativedelta
from time import strftime
import os
from openerp import tools
from openerp.osv import fields, osv
from openerp.tools.translate import _
import uuid
from openerp import SUPERUSER_ID
class survey_type(osv.osv):
_name = 'survey.type'
_description = 'Survey Type'
_columns = {
'name': fields.char("Name", size=128, required=1, translate=True),
'code': fields.char("Code", size=64),
}
class survey(osv.osv):
_name = 'survey'
_description = 'Survey'
_rec_name = 'title'
_inherit = ['mail.thread', 'ir.needaction_mixin']
def default_get(self, cr, uid, fields, context=None):
data = super(survey, self).default_get(cr, uid, fields, context)
return data
def _needaction_domain_get(self, cr, uid, context=None):
user_browse = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
model, group_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_survey_manager')
if group_id in [x.id for x in user_browse.groups_id]:
return ['&', ('response_ids.state', 'in', ['new', 'skip']), ('response_ids.partner_id.user_id', '=', uid)]
else:
return []
def _get_tot_start_survey(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, 0) for id in ids)
sur_res_obj = self.pool.get('survey.response')
for id in ids:
res[id] = sur_res_obj.search(cr, SUPERUSER_ID, [('survey_id', '=', id), ('state', '=', 'skip')], context=context, count=True)
return res
def _get_tot_comp_survey(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, 0) for id in ids)
sur_res_obj = self.pool.get('survey.response')
for id in ids:
res[id] = sur_res_obj.search(cr, SUPERUSER_ID, [('survey_id', '=', id), ('state', '=', 'done')], context=context, count=True)
return res
def _get_public_url(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, 0) for id in ids)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
survey_obj = self.pool.get('survey')
for survey_browse in survey_obj.browse(cr, uid, ids, context=context):
query = {
'db': cr.dbname
}
fragment = {
'active_id': survey_browse.id,
'action': 'survey.action_filling',
'params': survey_browse.token,
}
res[survey_browse.id] = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment)))
return res
_columns = {
'id': fields.integer('ID'),
'title': fields.char('Survey Title', size=128, required=1),
'title': fields.char('Survey Title', size=128, required=1, translate=True),
'page_ids': fields.one2many('survey.page', 'survey_id', 'Page'),
'date_open': fields.datetime('Survey Open Date', readonly=1),
'date_close': fields.datetime('Survey Close Date', readonly=1),
'max_response_limit': fields.integer('Maximum Answer Limit',
help="Set to one if survey is answerable only once"),
'response_user': fields.integer('Maximum Answer per User',
help="Set to one if you require only one Answer per user"),
'state': fields.selection([('open', 'Open'), ('cancel', 'Cancelled'),('close', 'Closed') ], 'Status', readonly=True),
'responsible_id': fields.many2one('res.users', 'Responsible', help="User responsible for survey"),
'tot_start_survey': fields.integer("Total Started Survey", readonly=1),
'tot_comp_survey': fields.integer("Total Completed Survey", readonly=1),
'note': fields.text('Description', size=128),
'history': fields.one2many('survey.history', 'survey_id', 'History Lines', readonly=True),
'users': fields.many2many('res.users', 'survey_users_rel', 'sid', 'uid', 'Users'),
'send_response': fields.boolean('Email Notification on Answer'),
'max_response_limit': fields.integer('Maximum Answer Limit', help="Set to one if survey is answerable only once"),
'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('close', 'Close'), ('cancel', 'Cancelled')], 'Status', required=1),
'visible_to_user': fields.boolean('Visible in the survey menu', help="If checked, survey users can see this survey in the kanban view."),
'authenticate': fields.boolean('A login is required', help="If checked, users who click on the public web link will be redirected to a login page where they must provide a login name and password. If unchecked, they may complete the survey directly."),
'tot_start_survey': fields.function(_get_tot_start_survey, string="Total Started Survey", type="integer"),
'tot_comp_survey': fields.function(_get_tot_comp_survey, string="Total Completed Survey", type="integer"),
'note': fields.text('Description', size=128, translate=True),
'type': fields.many2one('survey.type', 'Type'),
'color': fields.integer('Color Index'),
'invited_user_ids': fields.many2many('res.users', 'survey_invited_user_rel', 'sid', 'uid', 'Invited User'),
'response_ids': fields.one2many('survey.response', 'survey_id', 'Responses', readonly=1),
'public_url': fields.function(_get_public_url, string="Public web link", type="char"),
'token': fields.char('Public token', size=8, required=1),
'email_template_id': fields.many2one('email.template', 'Email Template', ondelete='set null'),
}
_defaults = {
'state': lambda * a: "open",
'tot_start_survey': lambda * a: 0,
'tot_comp_survey': lambda * a: 0,
'send_response': lambda * a: 1,
'response_user': lambda * a:1,
'state': "draft",
'visible_to_user': True,
'authenticate': True,
'date_open': fields.datetime.now,
'token': lambda s, cr, uid, c: uuid.uuid4(),
}
def survey_draft(self, cr, uid, ids, arg):
return self.write(cr, uid, ids, {'state': 'draft', 'date_open': None})
def survey_open(self, cr, uid, ids, arg):
self.write(cr, uid, ids, {'state': 'open', 'date_open': strftime("%Y-%m-%d %H:%M:%S")})
return True
return self.write(cr, uid, ids, {'state': 'open', 'date_open': datetime.now()})
def survey_close(self, cr, uid, ids, arg):
self.write(cr, uid, ids, {'state': 'close', 'date_close': strftime("%Y-%m-%d %H:%M:%S") })
return True
return self.write(cr, uid, ids, {'state': 'close', 'date_close': datetime.now()})
def survey_cancel(self, cr, uid, ids, arg):
self.write(cr, uid, ids, {'state': 'cancel' })
return True
return self.write(cr, uid, ids, {'state': 'cancel', 'date_close': datetime.now()})
def copy(self, cr, uid, ids, default=None, context=None):
vals = {}
current_rec = self.read(cr, uid, ids, context=context)
title = _("%s (copy)") % (current_rec.get('title'))
vals.update({'title': title})
vals.update({'history':[],'tot_start_survey':0,'tot_comp_survey':0})
return super(survey, self).copy(cr, uid, ids, vals, context=context)
def action_print_survey(self, cr, uid, ids, context=None):
@ -107,16 +139,18 @@ class survey(osv.osv):
@param context: A standard dictionary forcontextual values
@return: Dictionary value forprint survey form.
"""
page_setting = {'orientation': 'vertical', 'without_pagebreak': 0, 'paper_size': 'letter', 'page_number': 1, 'survey_title': 1}
if context is None:
context = {}
datas = {}
response_id = None
if 'response_id' in context:
response_id = context.get('response_id', 0)
datas['ids'] = [context.get('survey_id', 0)]
else:
elif 'print_response' in context:
response_id = self.pool.get('survey.response').search(cr, uid, [('survey_id', '=', ids)], context=context)
datas['ids'] = ids
page_setting = {'orientation': 'vertical', 'without_pagebreak': 0, 'paper_size': 'letter', 'page_number': 1, 'survey_title': 1}
report = {}
if response_id and response_id[0]:
context.update({'survey_id': datas['ids']})
@ -130,7 +164,6 @@ class survey(osv.osv):
'nodestroy': True,
}
else:
datas['form'] = page_setting
datas['model'] = 'survey.print'
report = {
@ -142,111 +175,143 @@ class survey(osv.osv):
}
return report
def fill_survey(self, cr, uid, ids, context=None):
sur_obj = self.read(cr, uid, ids,['title', 'page_ids'], context=context)
for sur in sur_obj:
name = sur['title']
pages = sur['page_ids']
if not pages:
raise osv.except_osv(_('Warning!'), _('This survey has no question defined. Please define the questions and answers first.'))
context.update({'active':False,'survey_id': ids[0]})
def print_statistics(self, cr, uid, ids, context=None):
"""
Print Survey Statistics in pdf format.
"""
return {
'type': 'ir.actions.report.xml',
'report_name': 'survey.analysis',
'datas': {
'model': 'survey.print.statistics',
'ids': [],
'form': {
'id': None,
'survey_ids': ids
},
},
}
def _check_valid(self, cr, uid, ids, context=None):
for survey in self.browse(cr, SUPERUSER_ID, ids, context=context):
if not survey.page_ids or not [page.question_ids for page in survey.page_ids if page.question_ids]:
raise osv.except_osv(_('Warning!'), _('This survey has no question defined or has no pages defined.'))
def action_fill_survey(self, cr, uid, ids, context=None):
id = ids[0]
survey = self.browse(cr, uid, id, context=context)
context.update({'edit': False, 'survey_id': id, 'survey_token': survey.token, 'ir_actions_act_window_target': 'inline'})
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'inline',
'name': survey.title,
'context': context
}
def action_test_survey(self, cr, uid, ids, context=None):
context.update({'survey_test': True})
return self.action_fill_survey(cr, uid, ids, context=context)
def action_edit_survey(self, cr, uid, ids, context=None):
id = ids[0]
context.update({
'survey_id': id,
'edit': True,
'ir_actions_act_window_target': 'new',
})
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'name': name,
'name': self.browse(cr, uid, id, context=context).title,
'context': context
}
def test_survey(self, cr, uid, ids, context=None):
sur_obj = self.read(cr, uid, ids,['title','page_ids'], context=context)
for sur in sur_obj:
name = sur['title']
pages = sur['page_ids']
if not pages:
raise osv.except_osv(_('Warning!'), _('This survey has no pages defined. Please define pages first.'))
context.update({'active':False,'survey_id': ids[0]})
def action_survey_sent(self, cr, uid, ids, context=None):
'''
This function opens a window to compose an email, with the survey template message loaded by default
'''
self._check_valid(cr, uid, ids, context=context)
survey_browse = self.pool.get('survey').browse(cr, uid, ids, context=context)[0]
if survey_browse.state != "open":
raise osv.except_osv(_('Warning!'), _("You cannot send invitations because the survey is not open."))
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
ir_model_data = self.pool.get('ir.model.data')
try:
template_id = ir_model_data.get_object_reference(cr, uid, 'survey', 'email_template_survey')[1]
except ValueError:
template_id = False
ctx = dict(context)
ctx.update({
'default_model': 'survey',
'default_res_id': ids[0],
'default_survey_id': ids[0],
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'survey_state': survey_browse.state
})
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'res_model': 'survey.mail.compose.message',
'target': 'new',
'name': name,
'context': context
'context': ctx,
}
def edit_survey(self, cr, uid, ids, context=None):
sur_obj = self.read(cr, uid, ids,['title','page_ids'], context=context)
for sur in sur_obj:
name = sur['title']
pages = sur['page_ids']
if not pages:
raise osv.except_osv(_('Warning!'), _('This survey has no question defined. Please define the questions and answers first.'))
context.update({'survey_id': ids[0]})
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'name': name,
'context': context
}
def unlink(self, cr, uid, ids, context=None):
email_template_ids = list()
for survey in self.browse(cr, uid, ids, context=context):
email_template_ids.append(survey.email_template_id.id)
if email_template_ids:
self.pool.get('email.template').unlink(cr, uid, email_template_ids, context=context)
return super(survey, self).unlink(cr, uid, ids, context=context)
class survey_history(osv.osv):
_name = 'survey.history'
_description = 'Survey History'
_rec_name = 'date'
_columns = {
'survey_id': fields.many2one('survey', 'Survey'),
'user_id': fields.many2one('res.users', 'User', readonly=True),
'date': fields.datetime('Date started', readonly=1),
}
_defaults = {
'date': lambda * a: datetime.datetime.now()
}
class survey_page(osv.osv):
_name = 'survey.page'
_description = 'Survey Pages'
_rec_name = 'title'
_order = 'sequence'
_columns = {
'title': fields.char('Page Title', size=128, required=1),
'title': fields.char('Page Title', size=128, required=1, translate=True),
'survey_id': fields.many2one('survey', 'Survey', ondelete='cascade'),
'question_ids': fields.one2many('survey.question', 'page_id', 'Questions'),
'sequence': fields.integer('Page Nr'),
'note': fields.text('Description'),
'note': fields.text('Description', translate=True),
}
_defaults = {
'sequence': lambda * a: 1
'sequence': 1
}
def default_get(self, cr, uid, fields, context=None):
if context is None:
context = {}
data = super(survey_page, self).default_get(cr, uid, fields, context)
if context.has_key('survey_id'):
if context.get('survey_id'):
data['survey_id'] = context.get('survey_id', False)
return data
def survey_save(self, cr, uid, ids, context=None):
if context is None:
context = {}
search_obj = self.pool.get('ir.ui.view')
search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
surv_name_wiz = self.pool.get('survey.name.wiz')
surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',0) })
surv_name_wiz = self.pool.get('survey.question.wiz')
surv_name_wiz.write(cr, uid, [context.get('wizard_id', False)], {'transfer': True, 'page_no': context.get('page_number', 0)})
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'search_view_id': search_id[0],
'context': context
}
@ -280,36 +345,38 @@ class survey_question(osv.osv):
return val
_columns = {
'page_id': fields.many2one('survey.page', 'Survey Page', ondelete='cascade', required=1),
'question': fields.char('Question', size=128, required=1),
'page_id': fields.many2one('survey.page', 'Survey Page', ondelete='cascade'),
'question': fields.char('Question', required=1, translate=True),
'answer_choice_ids': fields.one2many('survey.answer', 'question_id', 'Answer'),
'is_require_answer': fields.boolean('Require Answer to Question'),
'required_type': fields.selection([('all', 'All'), ('at least', 'At Least'), ('at most', 'At Most'), ('exactly', 'Exactly'), ('a range', 'A Range')], 'Respondent must answer'),
'req_ans': fields.integer('#Required Answer'),
'maximum_req_ans': fields.integer('Maximum Required Answer'),
'minimum_req_ans': fields.integer('Minimum Required Answer'),
'req_error_msg': fields.text('Error Message'),
'req_error_msg': fields.text('Error Message', translate=True),
'allow_comment': fields.boolean('Allow Comment Field'),
'sequence': fields.integer('Sequence'),
'tot_resp': fields.function(_calc_response, string="Total Answer"),
'survey': fields.related('page_id', 'survey_id', type='many2one', relation='survey', string='Survey'),
'descriptive_text': fields.text('Descriptive Text', size=255),
'tot_resp': fields.function(_calc_response, type="integer", string="Total Answer"),
'survey_id': fields.related('page_id', 'survey_id', type='many2one', relation='survey', string='Survey', store=True),
'descriptive_text': fields.text('Descriptive Text', translate=True),
'column_heading_ids': fields.one2many('survey.question.column.heading', 'question_id', ' Column heading'),
'type': fields.selection([('multiple_choice_only_one_ans', 'Multiple Choice (Only One Answer)'),
('multiple_choice_multiple_ans', 'Multiple Choice (Multiple Answer)'),
('matrix_of_choices_only_one_ans', 'Matrix of Choices (Only One Answers Per Row)'),
('matrix_of_choices_only_multi_ans', 'Matrix of Choices (Multiple Answers Per Row)'),
('matrix_of_drop_down_menus','Matrix of Drop-down Menus'),
('rating_scale','Rating Scale'),('single_textbox','Single Textbox'),
('rating_scale', 'Rating Scale'),
('single_textbox', 'Single Textbox'),
('multiple_textboxes', 'Multiple Textboxes'),
('multiple_textboxes_diff_type', 'Multiple Textboxes With Different Type'),
('comment', 'Comment/Essay Box'),
('numerical_textboxes','Numerical Textboxes'),('date','Date'),
('date_and_time','Date and Time'),('descriptive_text','Descriptive Text'),
('numerical_textboxes', 'Numerical Textboxes'),
('date', 'Date'),
('date_and_time', 'Date and Time'),
('descriptive_text', 'Descriptive Text'),
('table', 'Table'),
], 'Question Type', required=1, ),
'is_comment_require': fields.boolean('Add Comment Field'),
'comment_label': fields.char('Field Label', size = 255),
'comment_label': fields.char('Field Label', translate=True),
'comment_field_type': fields.selection([('char', 'Single Line Of Text'), ('text', 'Paragraph of Text')], 'Comment Field Type'),
'comment_valid_type': fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''),
('must_be_specific_length', 'Must Be Specific Length'),
@ -324,9 +391,9 @@ class survey_question(osv.osv):
'comment_maximum_float': fields.float('Maximum decimal number'),
'comment_minimum_date': fields.date('Minimum date'),
'comment_maximum_date': fields.date('Maximum date'),
'comment_valid_err_msg': fields.text('Error message'),
'comment_valid_err_msg': fields.text('Error message', translate=True),
'make_comment_field': fields.boolean('Make Comment Field an Answer Choice'),
'make_comment_field_err_msg': fields.text('Error message'),
'make_comment_field_err_msg': fields.text('Error message', translate=True),
'is_validation_require': fields.boolean('Validate Text'),
'validation_type': fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''), \
('must_be_specific_length', 'Must Be Specific Length'), \
@ -341,32 +408,33 @@ class survey_question(osv.osv):
'validation_maximum_float': fields.float('Maximum decimal number'),
'validation_minimum_date': fields.date('Minimum date'),
'validation_maximum_date': fields.date('Maximum date'),
'validation_valid_err_msg': fields.text('Error message'),
'validation_valid_err_msg': fields.text('Error message', translate=True),
'numeric_required_sum': fields.integer('Sum of all choices'),
'numeric_required_sum_err_msg': fields.text('Error message'),
'numeric_required_sum_err_msg': fields.text('Error message', translate=True),
'rating_allow_one_column_require': fields.boolean('Allow Only One Answer per Column (Forced Ranking)'),
'in_visible_rating_weight': fields.boolean('Is Rating Scale Invisible?'),
'in_visible_menu_choice': fields.boolean('Is Menu Choice Invisible?'),
'in_visible_answer_type': fields.boolean('Is Answer Type Invisible?'),
'comment_column': fields.boolean('Add comment column in matrix'),
'column_name': fields.char('Column Name',size=256),
'column_name': fields.char('Column Name', translate=True),
'no_of_rows': fields.integer('No of Rows'),
}
_defaults = {
'sequence': lambda * a: 1,
'type': lambda * a: 'multiple_choice_multiple_ans',
'req_error_msg': lambda * a: 'This question requires an answer.',
'required_type': lambda * a: 'at least',
'req_ans': lambda * a: 1,
'comment_field_type': lambda * a: 'char',
'comment_label': lambda * a: 'Other (please specify)',
'comment_valid_type': lambda * a: 'do_not_validate',
'comment_valid_err_msg': lambda * a : 'The comment you entered is in an invalid format.',
'validation_type': lambda * a: 'do_not_validate',
'validation_valid_err_msg': lambda * a : 'The comment you entered is in an invalid format.',
'numeric_required_sum_err_msg': lambda * a :'The choices need to add up to [enter sum here].',
'make_comment_field_err_msg': lambda * a : 'Please enter a comment.',
'in_visible_answer_type': lambda * a: 1
'sequence': 1,
'page_id': lambda s, cr, uid, c: c.get('page_id'),
'type': lambda s, cr, uid, c: _('multiple_choice_multiple_ans'),
'req_error_msg': lambda s, cr, uid, c: _('This question requires an answer.'),
'required_type': 'at least',
'req_ans': 1,
'comment_field_type': 'char',
'comment_label': lambda s, cr, uid, c: _('Other (please specify)'),
'comment_valid_type': 'do_not_validate',
'comment_valid_err_msg': lambda s, cr, uid, c: _('The comment you entered is in an invalid format.'),
'validation_type': 'do_not_validate',
'validation_valid_err_msg': lambda s, cr, uid, c: _('The comment you entered is in an invalid format.'),
'numeric_required_sum_err_msg': lambda s, cr, uid, c: _('The choices need to add up to [enter sum here].'),
'make_comment_field_err_msg': lambda s, cr, uid, c: _('Please enter a comment.'),
'in_visible_answer_type': 1
}
def on_change_type(self, cr, uid, ids, type, context=None):
@ -384,10 +452,6 @@ class survey_question(osv.osv):
val.update({'in_visible_rating_weight': False, 'in_visible_menu_choice': True})
return {'value': val}
elif type in ['matrix_of_drop_down_menus']:
val.update({'in_visible_rating_weight':True, 'in_visible_menu_choice':False})
return {'value': val}
elif type in ['single_textbox']:
val.update({'in_visible_rating_weight': True, 'in_visible_menu_choice': True})
return {'value': val}
@ -397,31 +461,31 @@ class survey_question(osv.osv):
'in_visible_answer_type': True})
return {'value': val}
def on_change_page_id(self, cr, uid, ids, page_id, context=None):
if page_id:
page = self.pool.get('survey.page').browse(cr, uid, page_id, context=context)
return {'survey_id': page.survey_id and page.survey_id.id}
return {'value': {}}
def write(self, cr, uid, ids, vals, context=None):
questions = self.read(cr, uid, ids, ['answer_choice_ids', 'type', 'required_type', \
'req_ans', 'minimum_req_ans', 'maximum_req_ans', 'column_heading_ids', 'page_id', 'question'])
for question in questions:
col_len = len(question['column_heading_ids'])
if vals.has_key('column_heading_ids'):
for col in vals['column_heading_ids']:
for col in vals.get('column_heading_ids', []):
if type(col[2]) == type({}):
col_len += 1
else:
col_len -= 1
if vals.has_key('type'):
que_type = vals['type']
else:
que_type = question['type']
que_type = vals.get('type', question['type'])
if que_type in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans',\
'matrix_of_drop_down_menus', 'rating_scale']:
if que_type in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'rating_scale']:
if not col_len:
raise osv.except_osv(_('Warning!'), _('You must enter one or more column headings for question "%s" of page %s.') % (question['question'], question['page_id'][1]))
ans_len = len(question['answer_choice_ids'])
if vals.has_key('answer_choice_ids'):
for ans in vals['answer_choice_ids']:
for ans in vals.get('answer_choice_ids', []):
if type(ans[2]) == type({}):
ans_len += 1
else:
@ -430,18 +494,14 @@ class survey_question(osv.osv):
if que_type not in ['descriptive_text', 'single_textbox', 'comment', 'table']:
if not ans_len:
raise osv.except_osv(_('Warning!'), _('You must enter one or more Answers for question "%s" of page %s.') % (question['question'], question['page_id'][1]))
req_type = ""
if vals.has_key('required_type'):
req_type = vals['required_type']
else:
req_type = question['required_type']
req_type = vals.get('required_type', question['required_type'])
if que_type in ['multiple_choice_multiple_ans', 'matrix_of_choices_only_one_ans', \
'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus',\
'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
'matrix_of_choices_only_multi_ans', 'rating_scale', 'multiple_textboxes', \
'numerical_textboxes', 'date', 'date_and_time']:
if req_type in ['at least', 'at most', 'exactly']:
if vals.has_key('req_ans'):
if 'req_ans' in vals:
if not vals['req_ans'] or vals['req_ans'] > ans_len:
raise osv.except_osv(_('Warning!'), _("#Required Answer you entered \
is greater than the number of answer. \
@ -455,114 +515,65 @@ class survey_question(osv.osv):
if req_type == 'a range':
minimum_ans = 0
maximum_ans = 0
if vals.has_key('minimum_req_ans'):
minimum_ans = vals['minimum_req_ans']
if not vals['minimum_req_ans'] or vals['minimum_req_ans'] > ans_len:
raise osv.except_osv(_('Warning!'),_("Minimum Required Answer\
you entered is greater than the number of answer.\
Please use a number that is smaller than %d.") % (ans_len + 1))
else:
minimum_ans = question['minimum_req_ans']
if not question['minimum_req_ans'] or question['minimum_req_ans'] > ans_len:
minimum_ans = 'minimum_req_ans' in vals and vals['minimum_req_ans'] or question['minimum_req_ans']
maximum_ans = 'maximum_req_ans' in vals and vals['maximum_req_ans'] or question['maximum_req_ans']
if not minimum_ans or minimum_ans > ans_len or not maximum_ans or maximum_ans > ans_len:
raise osv.except_osv(_('Warning!'), _("Minimum Required Answer you\
entered is greater than the number of answer. \
Please use a number that is smaller than %d.") % (ans_len + 1))
if vals.has_key('maximum_req_ans'):
maximum_ans = vals['maximum_req_ans']
if not vals['maximum_req_ans'] or vals['maximum_req_ans'] > ans_len:
raise osv.except_osv(_('Warning!'),_("Maximum Required Answer you \
entered for your maximum is greater than the number of answer.\
Please use a number that is smaller than %d.") % (ans_len + 1))
else:
maximum_ans = question['maximum_req_ans']
if not question['maximum_req_ans'] or question['maximum_req_ans'] > ans_len:
raise osv.except_osv(_('Warning!'),_("Maximum Required Answer you\
entered for your maximum is greater than the number of answer.\
Please use a number that is smaller than %d.") % (ans_len + 1))
if maximum_ans <= minimum_ans:
raise osv.except_osv(_('Warning!'), _("Maximum Required Answer is greater \
than Minimum Required Answer"))
if question['type'] == 'matrix_of_drop_down_menus' and vals.has_key('column_heading_ids'):
for col in vals['column_heading_ids']:
if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices\
in column heading."))
elif not col[2] or not col[2].has_key('menu_choice') or\
col[2]['menu_choice'].strip() == '':
raise osv.except_osv(_('Warning!'),_("You must enter one or more menu \
choices in column heading (white spaces not allowed)."))
return super(survey_question, self).write(cr, uid, ids, vals, context=context)
def create(self, cr, uid, vals, context=None):
minimum_ans = 0
maximum_ans = 0
page = self.pool.get('survey.page').browse(cr, uid, int(vals.get('page_id', 0)), context=context).title
if vals.has_key('answer_choice_ids') and not len(vals['answer_choice_ids']):
if vals.has_key('type') and vals['type'] not in ['descriptive_text', 'single_textbox', 'comment','table']:
raise osv.except_osv(_('Warning!'),_('You must enter one or more answers for question "%s" of page %s .') % (vals['question'], page))
page = self.pool.get('survey.page').browse(cr, uid, 'page_id' in vals and vals['page_id'] or context['page_id'], context=context)
if 'answer_choice_ids' in vals and not len(vals.get('answer_choice_ids', [])) and \
vals.get('type') not in ['descriptive_text', 'single_textbox', 'comment', 'table']:
raise osv.except_osv(_('Warning!'), _('You must enter one or more answers for question "%s" of page %s .') % (vals['question'], page.title))
if vals.has_key('column_heading_ids') and not len(vals['column_heading_ids']):
if vals.has_key('type') and vals['type'] in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']:
raise osv.except_osv(_('Warning!'),_('You must enter one or more column headings for question "%s" of page %s.')% (vals['question'], page))
if 'column_heading_ids' in vals and not len(vals.get('column_heading_ids', [])) and \
vals.get('type') in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'rating_scale']:
raise osv.except_osv(_('Warning!'), _('You must enter one or more column headings for question "%s" of page %s.') % (vals['question'], page.title))
if vals['type'] in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] in ['at least', 'at most', 'exactly']:
if vals.has_key('answer_choice_ids') and vals['req_ans'] > len(vals['answer_choice_ids']) or not vals['req_ans']:
if 'is_require_answer' in vals and vals.get('type') in ['multiple_choice_multiple_ans', 'matrix_of_choices_only_one_ans', \
'matrix_of_choices_only_multi_ans', 'rating_scale', 'multiple_textboxes', 'numerical_textboxes', 'date', 'date_and_time']:
if vals.get('required_type') in ['at least', 'at most', 'exactly']:
if 'answer_choice_ids' in vals and 'answer_choice_ids' in vals and vals.get('req_ans') > len(vals.get('answer_choice_ids', [])):
raise osv.except_osv(_('Warning!'), _("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids']) + 1))
if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] == 'a range':
minimum_ans = vals['minimum_req_ans']
maximum_ans = vals['maximum_req_ans']
if vals.has_key('answer_choice_ids') or vals['minimum_req_ans'] > len(vals['answer_choice_ids']) or not vals['minimum_req_ans']:
if vals.get('required_type') == 'a range':
if 'answer_choice_ids' in vals:
if not vals.get('minimum_req_ans') or vals['minimum_req_ans'] > len(vals['answer_choice_ids']):
raise osv.except_osv(_('Warning!'), _("Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids']) + 1))
if vals.has_key('answer_choice_ids') or vals['maximum_req_ans'] > len(vals['answer_choice_ids']) or not vals['maximum_req_ans']:
if not vals.get('maximum_req_ans') or vals['maximum_req_ans'] > len(vals['answer_choice_ids']):
raise osv.except_osv(_('Warning!'), _("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids']) + 1))
if maximum_ans <= minimum_ans:
if vals.get('maximum_req_ans', 0) <= vals.get('minimum_req_ans', 0):
raise osv.except_osv(_('Warning!'), _("Maximum Required Answer is greater than Minimum Required Answer."))
if vals['type'] == 'matrix_of_drop_down_menus':
for col in vals['column_heading_ids']:
if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices in column heading."))
elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '':
raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices in column heading (white spaces not allowed)."))
res = super(survey_question, self).create(cr, uid, vals, context)
return res
return super(survey_question, self).create(cr, uid, vals, context)
def survey_save(self, cr, uid, ids, context=None):
if context is None:
context = {}
search_obj = self.pool.get('ir.ui.view')
search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
surv_name_wiz = self.pool.get('survey.name.wiz')
surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',False) })
surv_name_wiz = self.pool.get('survey.question.wiz')
surv_name_wiz.write(cr, uid, [context.get('wizard_id', False)], {'transfer': True, 'page_no': context.get('page_number', False)})
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'search_view_id': search_id[0],
'context': context
}
def default_get(self, cr, uid, fields, context=None):
if context is None:
context = {}
data = super(survey_question, self).default_get(cr, uid, fields, context)
if context.has_key('page_id'):
data['page_id']= context.get('page_id', False)
return data
class survey_question_column_heading(osv.osv):
_name = 'survey.question.column.heading'
_description = 'Survey Question Column Heading'
_rec_name = 'title'
_order = 'sequence'
def _get_in_visible_rating_weight(self, cr, uid, context=None):
if context is None:
@ -570,6 +581,7 @@ class survey_question_column_heading(osv.osv):
if context.get('in_visible_rating_weight', False):
return context['in_visible_rating_weight']
return False
def _get_in_visible_menu_choice(self, cr, uid, context=None):
if context is None:
context = {}
@ -578,7 +590,8 @@ class survey_question_column_heading(osv.osv):
return False
_columns = {
'title': fields.char('Column Heading', size=128, required=1),
'title': fields.char('Column Heading', size=128, required=1, translate=True),
'sequence': fields.integer('Sequence'),
'menu_choice': fields.text('Menu Choice'),
'rating_weight': fields.integer('Weight'),
'question_id': fields.many2one('survey.question', 'Question', ondelete='cascade'),
@ -590,6 +603,7 @@ class survey_question_column_heading(osv.osv):
'in_visible_menu_choice': _get_in_visible_menu_choice,
}
class survey_answer(osv.osv):
_name = 'survey.answer'
_description = 'Survey Answer'
@ -601,7 +615,7 @@ class survey_answer(osv.osv):
for rec in self.browse(cr, uid, ids, context=context):
cr.execute("select count(question_id), (select count(answer_id) \
from survey_response_answer sra, survey_response_line sa \
where sra.response_id = sa.id and sra.answer_id = %d \
where sra.response_line_id = sa.id and sra.answer_id = %d \
and sa.state='done') as tot_ans from survey_response_line \
where question_id = %d and state = 'done'"\
% (rec.id, rec.question_id.id))
@ -623,19 +637,18 @@ class survey_answer(osv.osv):
_columns = {
'question_id': fields.many2one('survey.question', 'Question', ondelete='cascade'),
'answer': fields.char('Answer', size=128, required=1),
'answer': fields.char('Answer', size=128, required=1, translate=True),
'sequence': fields.integer('Sequence'),
'response': fields.function(_calc_response_avg, string="#Answer", multi='sums'),
'average': fields.function(_calc_response_avg, string="#Avg", multi='sums'),
'type': fields.selection([('char', 'Character'), ('date', 'Date'), ('datetime', 'Date & Time'), \
('integer', 'Integer'), ('float', 'Float'), ('selection', 'Selection'), \
('email', 'Email')], "Type of Answer", required=1),
'menu_choice': fields.text('Menu Choices'),
'menu_choice': fields.text('Menu Choices', translate=True),
'in_visible_answer_type': fields.boolean('Is Answer Type Invisible??')
}
_defaults = {
# 'sequence' : lambda * a: 1,
'type' : lambda * a: 'char',
'type': 'char',
'in_visible_answer_type': _get_in_visible_answer_type,
}
@ -649,28 +662,90 @@ class survey_answer(osv.osv):
class survey_response(osv.osv):
_name = "survey.response"
_rec_name = 'date_create'
_columns = {
'survey_id' : fields.many2one('survey', 'Survey', required=1, ondelete='cascade'),
'date_deadline': fields.date("Deadline date", help="Date by which the person can respond to the survey"),
'survey_id': fields.many2one('survey', 'Survey', required=1, readonly=1, ondelete='restrict'),
'date_create': fields.datetime('Create Date', required=1),
'user_id' : fields.many2one('res.users', 'User'),
'response_type' : fields.selection([('manually', 'Manually'), ('link', 'Link')], \
'Answer Type', required=1, readonly=1),
'response_type': fields.selection([('manually', 'Manually'), ('link', 'Link')], 'Answer Type', required=1),
'question_ids': fields.one2many('survey.response.line', 'response_id', 'Answer'),
'state' : fields.selection([('done', 'Finished '),('skip', 'Not Finished')], \
'Status', readonly=True),
'state': fields.selection([('new', 'Not Started'), ('skip', 'Not Finished'), ('done', 'Finished'), ('cancel', 'Canceled'), ('test', 'Test')], 'Status', readonly=True),
'token': fields.char("Indentification token", readonly=1),
'partner_id': fields.many2one('res.partner', 'Partner', readonly=1),
'email': fields.char("Email", size=64, readonly=1),
}
_defaults = {
'state' : lambda * a: "skip",
'response_type' : lambda * a: "manually",
'date_create': datetime.now(),
'state': "new",
'response_type': "manually",
'token': lambda s, cr, uid, c: uuid.uuid4(),
}
def action_survey_resent(self, cr, uid, ids, context=None):
record = self.browse(cr, uid, ids[0], context=context)
context = context or {}
context.update({
'survey_resent_token': True,
'default_partner_ids': record.partner_id and [record.partner_id.id] or [],
'default_multi_email': record.email or "",
'default_public': 'email_private',
})
return self.pool.get('survey').action_survey_sent(cr, uid, [record.survey_id.id], context=context)
def action_print_response(self, cr, uid, ids, context=None):
"""
Print Survey Answer in pdf format.
@return : Dictionary value for created survey answer report
"""
return {
'type': 'ir.actions.report.xml',
'report_name': 'survey.browse.response',
'datas': {
'model': 'survey.print.statistics',
'form': {
'response_ids': ids,
'orientation': 'vertical',
'paper_size': 'letter',
'page_number': 0,
'without_pagebreak': 0
}
},
}
def action_preview(self, cr, uid, ids, context=None):
"""
Get preview response
"""
context = context or {}
self.pool.get('survey').check_access_rights(cr, uid, 'write')
record = self.browse(cr, uid, ids[0], context=context)
context.update({
'ir_actions_act_window_target': 'new',
'survey_id': record.survey_id.id,
'response_id': ids[0],
'readonly': True,
})
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'context': context
}
def action_cancel(self, cr, uid, ids, context=None):
self.pool.get('survey').check_access_rights(cr, uid, 'write')
return self.write(cr, uid, ids, {'state': 'cancel'})
def name_get(self, cr, uid, ids, context=None):
if not len(ids):
return []
reads = self.read(cr, uid, ids, ['user_id','date_create'], context=context)
reads = self.read(cr, uid, ids, ['partner_id', 'date_create'], context=context)
res = []
for record in reads:
name = (record['user_id'] and record['user_id'][1] or '' )+ ' (' + record['date_create'].split('.')[0] + ')'
name = (record['partner_id'] and record['partner_id'][1] or '') + ' (' + record['date_create'].split('.')[0] + ')'
res.append((record['id'], name))
return res
@ -685,94 +760,32 @@ class survey_response_line(osv.osv):
_columns = {
'response_id': fields.many2one('survey.response', 'Answer', ondelete='cascade'),
'date_create': fields.datetime('Create Date', required=1),
'state': fields.selection([('draft', 'Draft'), ('done', 'Answered'),('skip', 'Skiped')],\
'Status', readonly=True),
'question_id': fields.many2one('survey.question', 'Question'),
'page_id': fields.related('question_id', 'page_id', type='many2one', \
relation='survey.page', string='Page'),
'response_answer_ids': fields.one2many('survey.response.answer', 'response_id', 'Answer'),
'response_table_ids': fields.one2many('survey.tbl.column.heading', \
'response_table_id', 'Answer'),
'state': fields.selection([('draft', 'Draft'), ('done', 'Answered'), ('skip', 'Skiped')], 'Status', readonly=True),
'question_id': fields.many2one('survey.question', 'Question', ondelete='restrict'),
'page_id': fields.related('question_id', 'page_id', type='many2one', relation='survey.page', string='Page', ondelete='restrict'),
'response_answer_ids': fields.one2many('survey.response.answer', 'response_line_id', 'Answer'),
'comment': fields.text('Notes'),
'single_text': fields.char('Text', size=255),
}
_defaults = {
'state' : lambda * a: "draft",
}
class survey_tbl_column_heading(osv.osv):
_name = 'survey.tbl.column.heading'
_order = 'name'
_columns = {
'name': fields.integer('Row Number'),
'column_id': fields.many2one('survey.question.column.heading', 'Column'),
'value': fields.char('Value', size = 255),
'response_table_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'),
'state': "draft",
}
class survey_response_answer(osv.osv):
_name = 'survey.response.answer'
_description = 'Survey Answer'
_rec_name = 'response_id'
_rec_name = 'response_line_id'
_columns = {
'response_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'),
'name': fields.integer('Row Number'),
'response_line_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'),
'answer_id': fields.many2one('survey.answer', 'Answer', required=1, ondelete='cascade'),
'column_id': fields.many2one('survey.question.column.heading', 'Column'),
'answer': fields.char('Value', size=255),
'value_choice': fields.char('Value Choice', size=255),
'comment': fields.text('Notes'),
'comment_field': fields.char('Comment', size = 255)
'comment_field': fields.char('Comment', size=255),
'value': fields.char('Value', size=255),
}
class res_users(osv.osv):
_inherit = "res.users"
_name = "res.users"
_columns = {
'survey_id': fields.many2many('survey', 'survey_users_rel', 'uid', 'sid', 'Groups'),
}
class survey_request(osv.osv):
_name = "survey.request"
_order = 'date_deadline'
_rec_name = 'date_deadline'
_columns = {
'date_deadline': fields.date("Deadline date"),
'user_id': fields.many2one("res.users", "User"),
'email': fields.char("Email", size=64),
'survey_id': fields.many2one("survey", "Survey", required=1, ondelete='cascade'),
'response': fields.many2one('survey.response', 'Answer'),
'state': fields.selection([('draft','Draft'),('cancel', 'Cancelled'),('waiting_answer', 'Waiting Answer'),('done', 'Done')], 'Status', readonly=1)
}
_defaults = {
'state': lambda * a: 'draft',
# 'date_deadline': lambda * a : (datetime.now() + relativedelta(months=+1)).strftime("%Y-%m-%d %H:%M:%S")
}
def survey_req_waiting_answer(self, cr, uid, ids, arg):
self.write(cr, uid, ids, { 'state' : 'waiting_answer'})
return True
def survey_req_draft(self, cr, uid, ids, arg):
self.write(cr, uid, ids, { 'state' : 'draft'})
return True
def survey_req_done(self, cr, uid, ids, arg):
self.write(cr, uid, ids, { 'state' : 'done'})
return True
def survey_req_cancel(self, cr, uid, ids, arg):
self.write(cr, uid, ids, { 'state' : 'cancel'})
return True
def on_change_user(self, cr, uid, ids, user_id, context=None):
if user_id:
user_obj = self.pool.get('res.users')
user = user_obj.browse(cr, uid, user_id, context=context)
return {'value': {'email': user.email}}
return {}
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:

View File

@ -1,17 +1,10 @@
<?xml version="1.0"?>
<openerp>
<data>
<data noupdate="1">
<record model="survey.type" id="survey_type1">
<field name="name">Human Resources</field>
<field name="code">Human Resources</field>
</record>
<record model="survey.type" id="survey_type2">
<field name="name">Customer Feeback</field>
<field name="code">Customer Feeback</field>
</record>
<record model="survey.type" id="survey_type3">
</record><record model="survey.type" id="survey_type2">
<field name="name">Supplier Selection</field>
<field name="code">Supplier Selection</field>
</record>
</data>
</openerp>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
-
In order to check Survey Request of the survey "Initial Partner Feedback" I create a Survey Request for survey "Initial Partner Feedback".
-
!record {model: survey.request, id: survey_request_1}:
survey_id: survey_Initial_partner_feedback
user_id: base.user_demo
-
!assert {model: survey.request, id: survey_request_1, string: Survey Request should be in draft state}:
- state == 'draft'
-
I set Survey Request for the survey in waiting state.
-
!python {model: survey.request}: |
self.survey_req_waiting_answer(cr, uid, [ref("survey_request_1")], context)
-
I check that state of Survey Request for the survey is waiting or not.
-
!assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in waiting state}:
- state == 'waiting_answer'
-
I cancel the Survey Request of the survey.
-
!python {model: survey.request}: |
self.survey_req_cancel(cr, uid, [ref("survey_request_1")], context)
-
I check that state of Survey Request of the survey is cancel or not.
-
!assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in cancel state}:
- state == 'cancel'
-
I set Survey Request of the survey in draft state.
-
!python {model: survey.request}: |
self.survey_req_draft(cr, uid, [ref("survey_request_1")], context)
-
I check that state of Survey request of the survey is draft or not.
-
!assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in draft state}:
- state == 'draft'
-
I set survey request of the survey in done state.
-
!python {model: survey.request}: |
self.survey_req_waiting_answer(cr, uid, [ref("survey_request_1")], context)
self.survey_req_done(cr, uid, [ref("survey_request_1")], context)
-
I check that state of Survey request of the survey is done or not.
-
!assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in done state}:
- state == 'done'

View File

@ -1,111 +0,0 @@
-
In order to check the survey module in OpenERP I use the survey "Initial Partner Feedback".
-
I set the survey in Open state.
-
!python {model: survey}: |
sur = self.survey_open(cr, uid, [ref("survey_Initial_partner_feedback")], context)
-
I check state of survey is open or not.
-
!assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in open state}:
- state == 'open'
-
I check that the survey is reopened or not.
-
!python {model: survey}: |
self.survey_cancel(cr, uid, [ref('survey_Initial_partner_feedback')],context)
self.survey_open(cr, uid, [ref('survey_Initial_partner_feedback')],context)
-
I check that state of survey is open or not.
-
!assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in open state}:
- state == 'open'
-
I set the state of the survey open.
-
!python {model: survey}: |
sur = self.survey_open(cr, uid, [ref("survey_Initial_partner_feedback")], context)
-
In order to print the survey I click on Print.
-
!python {model: survey.print}: |
id = self.create(cr, uid, {'survey_ids': [(6,0,[ref('survey.survey_Initial_partner_feedback')])]})
self.action_next(cr, uid, [id], context)
-
In order to answer the survey I click on "Answer a Survey" wizard.
-
!python {model: survey.name.wiz}: |
id = self.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
self.action_next(cr, uid, [id], context)
-
I give the answer of the first and second page of the survey.
-
!python {model: survey.question.wiz}: |
ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')]}
self.fields_view_get(cr, uid, ref("survey.view_survey_question_message"),"form", context=ctx)
values = self.default_get(cr, uid, ['name'], ctx)
id = self.create(cr, uid, {str(ref("survey_initial_question_company_name")) +"_single" :'Tiny' , str(ref("survey_initial_question_company_size")) + "_selection" : int(ref("survey.survey_initial_question_company_size_51")), }, context)
self.action_next(cr, uid, [id], context)
id = self.create(cr, uid, {str(ref("survey_initial_question_contract_customers")) + "_selection" : int(ref("survey_initial_answer_sometimes")), str(ref("survey_initial_question_sell_to_your_customers")) + "_selection" : int(ref("survey_initial_answer_maintenance_contract")), }, context)
self.action_next(cr, uid, [id], context)
-
I print the answers of the survey.
-
!python {model: survey.browse.answer}: |
id = self.create(cr, uid, {'survey_id': ref('survey.survey_Initial_partner_feedback')})
self.action_next(cr, uid, [id], context)
-
I edit questions of the survey as per requirement.
-
!python {model: survey.question.wiz}: |
name_wiz_obj = self.pool.get('survey.name.wiz')
id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')], 'question_id': ref('survey_initial_question_company_name'), 'page_number': -1,'sur_name_id': id}
self.action_edit_question(cr, uid, [ref('survey_initial_question_company_name')], context = ctx)
self.action_delete_question(cr, uid, [ref('survey_initial_question_company_name')], context = ctx)
self.action_new_question(cr, uid, [], context = ctx)
-
I edit Page of the survey as per requirement.
-
!python {model: survey.question.wiz}: |
name_wiz_obj = self.pool.get('survey.name.wiz')
id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')], 'page_id': ref('survey_initial_page_Contracts'), 'sur_name_id': id}
self.action_edit_page(cr, uid, [ref('survey_initial_page_Contracts')], context = ctx)
self.action_delete_page(cr, uid, [ref('survey_initial_page_Contracts')], context = ctx)
self.action_new_page(cr, uid, [], context = ctx)
-
In order to send invitation to the users I click on "Send Invitation" wizard.
-
!python {model: survey.send.invitation}: |
context = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')]}
values = self.default_get(cr, uid, ['mail_from', 'mail_subject', 'send_mail_existing', 'mail_subject_existing', 'mail', 'partner_ids', 'send_mail'], context)
values['mail_from'] = 'Surveyor'
new_id = self.create(cr, uid, values)
self.action_send(cr, uid, [new_id], context)
-
I set the value in "Total start survey" field.
-
!record {model: survey, id: survey_Initial_partner_feedback}:
tot_start_survey: 1
-
I set the survey in Cancel state.
-
!python {model: survey}: |
self.survey_cancel(cr, uid, [ref("survey_Initial_partner_feedback")], context)
-
I check state of survey is cancel or not.
-
!assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in cancel state}:
- state == 'cancel'
-
I set the survey in close state.
-
!python {model: survey}: |
self.survey_close(cr, uid, [ref("survey_Initial_partner_feedback")], context)
-
I check state of Survey is close or not.
-
!assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in close state}:
- state == 'close'

View File

@ -1,6 +0,0 @@
-
I check the question type of the survey "Initial Partner Feedback".
-
!python {model: survey.question}: |
sur_question = self.on_change_type(cr, uid, [ref("survey_Initial_partner_feedback")], 'multiple_textboxes_diff_type')
assert sur_question

View File

@ -0,0 +1,117 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv.orm import except_orm
from openerp.tools import mute_logger
from time import time
class test_survey_answer():
def setUp(self):
cr, uid = self.cr, self.uid
# Usefull models
self.ir_model = self.registry('ir.model')
self.ir_model_data = self.registry('ir.model.data')
self.obj_survey = self.registry('survey')
self.obj_survey_response = self.registry('survey.response')
self.obj_survey_question_wiz = self.registry('survey.question.wiz')
self.obj_survey_print = self.registry('survey.print')
self.survey_id = self.obj_survey.create(cr, uid, {
'title': 'Initial Partner Feedback',
'max_response_limit': 20,
'type': ref("survey_type2"),
'state': 'draft',
'authenticate': 0,
'date_open': time.strftime('%Y-%m-%d %H:%M:%S')
})
self.survey_browse = self.obj_survey.browse(cr, uid, self.survey_id, context)
#@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
def test_00_survey_public(self):
cr, uid = self.cr, self.uid
# In order to check the survey module in OpenERP I use the survey "Initial Partner Feedback".
# I set the survey in Open state.
self.obj_survey.survey_open(cr, uid, [self.survey_id], context)
# I check state of survey is open or not.
self.assertEqual(self.survey_browse.state, 'open', 'Survey should be in open state')
# I check that the survey is reopened or not.
self.obj_survey.survey_cancel(cr, uid, [self.survey_id], context)
self.obj_survey.survey_open(cr, uid, [self.survey_id], context)
self.assertEqual(self.survey_browse.state, 'open', 'Survey should be in open state again')
# I set the state of the survey open.
self.obj_survey.survey_open(cr, uid, [self.survey_id], context)
# In order to print the survey I click on Print.
id = self.obj_survey_print.create(cr, uid, {'survey_ids': [(6, 0, [self.survey_id])]})
self.obj_survey_print.action_next(cr, uid, [id], context)
# In order to answer the survey I click on "Answer a Survey" with a public token.
ctx = {}
ctx.update({'survey_id': self.survey_id, 'survey_token': self.survey_browse.token})
fields_view = self.obj_survey_question_wiz.fields_view_get(self, cr, uid, view_id=None, view_type='form', context=ctx)
id = self.obj_survey_question_wiz.create(cr, uid, {}, ctx)
self.obj_survey_question_wiz.action_next(cr, uid, [id], ctx)
# # I give the answer of the first and second page of the survey.
# #ctx = {'active_model':'survey', 'active_id': self.survey_id, 'active_ids': [self.survey_id]}
# self.obj_survey_question_wiz.fields_view_get(cr, uid, ref("survey.view_survey_question_message"),"form", context=ctx)
# values = self.obj_survey_question_wiz.default_get(cr, uid, ['name'], ctx)
# id = self.obj_survey_question_wiz.create(cr, uid, {str(ref("survey_initial_question_company_name")) +"_single" :'Tiny' , str(ref("survey_initial_question_company_size")) + "_selection" : int(ref("survey.survey_initial_question_company_size_51")), }, context)
# self.obj_survey_question_wiz.action_next(cr, uid, [id], context)
# id = self.obj_survey_question_wiz.create(cr, uid, {str(ref("survey_initial_question_contract_customers")) + "_selection" : int(ref("survey_initial_answer_sometimes")), str(ref("survey_initial_question_sell_to_your_customers")) + "_selection" : int(ref("survey_initial_answer_maintenance_contract")), }, context)
# self.obj_survey_question_wiz.action_next(cr, uid, [id], context)
# # I edit questions of the survey as per requirement.
# id = self.obj_survey_name_wiz.create(cr, uid, {'survey_id': self.survey_id})
# ctx.update({'question_id': ref('survey_initial_question_company_name'), 'page_number': -1, 'sur_name_id': id})
# self.obj_survey_question_wiz.action_edit_question(cr, uid, [ref('survey_initial_question_company_name')], context=ctx)
# self.obj_survey_question_wiz.action_delete_question(cr, uid, [ref('survey_initial_question_company_name')], context=ctx)
# self.obj_survey_question_wiz.action_new_question(cr, uid, [], context=ctx)
# # I edit Page of the survey as per requirement.
# id = self.obj_survey_name_wiz.create(cr, uid, {'survey_id': self.survey_id})
# ctx.update({'page_id': ref('survey_initial_page_Contracts'), 'sur_name_id': id})
# self.obj_survey_question_wiz.action_edit_page(cr, uid, [ref('survey_initial_page_Contracts')], context=ctx)
# self.obj_survey_question_wiz.action_delete_page(cr, uid, [ref('survey_initial_page_Contracts')], context=ctx)
# self.obj_survey_question_wiz.action_new_page(cr, uid, [], context=ctx)
# # In order to send invitation to the users I click on "Send Invitation" wizard.
# # I set the survey in Cancel state.
# self.obj_survey.survey_cancel(cr, uid, [self.survey_id], context)
# # I check state of survey is cancel or not.
# self.assertEqual(self.survey_browse.state, 'cancel', 'Survey should be in cancel state')
# # I set the survey in close state.
# self.obj_survey.survey_close(cr, uid, [self.survey_id], context)
# # I check state of Survey is close or not.
# self.assertEqual(self.survey_browse.state, 'close', 'Survey should be in cancel state')
# # sur_question = self.on_change_type(cr, uid, [ref("survey_Initial_partner_feedback")], 'multiple_textboxes_diff_type')

View File

@ -19,11 +19,9 @@
#
##############################################################################
import survey_send_invitation
import survey_email_compose_message
import survey_print_statistics
import survey_print_answer
import survey_browse_answer
import survey_selection
import survey_answer
import survey_print

File diff suppressed because it is too large Load Diff

View File

@ -9,22 +9,30 @@
<field name="name">Survey Answer</field>
<field name="model">survey.question.wiz</field>
<field name="arch" type="xml">
<form string="Your Messages" version="7.0">
<field name="name" nolabel="1" colspan="4" />
<form string="Your Survey" version="7.0">
<field name="survey_id" nolabel="1" colspan="4" invisible="1"/>
<sheet>
<div>
<br/><br/>
<h2>Thanks for completing this survey.</h2>
</div>
<div groups="portal.group_anonymous">
<h2>Now join OpenERP to facilitate your professional life.</h2>
<ul style="margin-top: 26px;">
<li>Surveys</li>
<li>Accounting</li>
<li>CRM and Marketing</li>
<li>Project Managment</li>
<li>...</li>
</ul>
<div style="margin-bottom: 20px;margin-top: 30px;font-weight: bold;">Register with OpenERP today!</div>
<a href="https://accounts.openerp.com/" class="oe_survey_button">Sign Up FREE</a>
</div>
</sheet>
</form>
</field>
</record>
<record id="view_survey_question_message1" model="ir.ui.view">
<field name="name">Survey Search</field>
<field name="model">survey.question.wiz</field>
<field name="arch" type="xml">
<search string="Your Messages">
<field name="name"/>
</search>
</field>
</record>
<record id="action_view_survey_question_message" model="ir.actions.act_window">
<field name="type">ir.actions.act_window</field>
<field name="res_model">survey.question.wiz</field>
@ -33,5 +41,14 @@
<field name="target">new</field>
</record>
<record id="action_filling" model="ir.actions.server">
<field name="name">Filling Survey</field>
<field name="type">ir.actions.server</field>
<field name="state">code</field>
<field name="model_id" ref="model_survey_question_wiz"/>
<field name="code">action = self._action_filling(cr, uid, None, context)</field>
<field name="condition">True</field>
</record>
</data>
</openerp>

View File

@ -1,59 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
class survey_browse_answer(osv.osv_memory):
_name = 'survey.browse.answer'
_columns = {
'survey_id': fields.many2one('survey', "Survey", required="1"),
'response_id': fields.many2one("survey.response", "Survey Answers", help="If this field is empty, all answers of the selected survey will be print."),
}
def action_next(self, cr, uid, ids, context=None):
"""
Open Browse Response wizard. if you select only survey_id then this wizard open with all response_ids and
if you select survey_id and response_id then open the particular response of the survey.
"""
if context is None: context = {}
record = self.read(cr, uid, ids, [])
record = record and record[0] or {}
if record['response_id']:
res_id = [(record.get('response_id') and record['response_id'][0])]
else:
sur_response_obj = self.pool.get('survey.response')
res_id = sur_response_obj.search(cr, uid, [('survey_id', '=', record['survey_id'][0])])
context.update({'active' : True,'survey_id' : record['survey_id'][0], 'response_id' : res_id, 'response_no' : 0})
search_obj = self.pool.get('ir.ui.view')
search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'search_view_id':search_id[0],
'context' : context
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,42 +0,0 @@
<?xml version="1.0" ?>
<openerp>
<data>
<!--
Browse Response Wizard (Survey Browse answer)
-->
<record id="view_survey_answer" model="ir.ui.view">
<field name="name">Survey</field>
<field name="model">survey.browse.answer</field>
<field name="arch" type="xml">
<form string="Survey" version="7.0">
<group col="4">
<field name="survey_id"/>
<field name="response_id" domain="[('survey_id','=', survey_id)]"/>
</group>
<footer>
<button name="action_next" string="Start" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_browse_survey_response"
model="ir.actions.act_window">
<field name="name">Answer Survey</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">survey.browse.answer</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem name="Browse Answers" id="menu_browse_survey_response"
action="action_browse_survey_response" parent="base.next_id_10"
groups="base.group_tool_manager" icon="STOCK_PRINT_PREVIEW"/>
</data>
</openerp>

View File

@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
import re
from openerp.osv import osv
from openerp.osv import fields
from datetime import datetime
from openerp.tools.translate import _
import uuid
emails_split = re.compile(r"[;,\n\r]+")
class survey_mail_compose_message(osv.TransientModel):
_name = 'survey.mail.compose.message'
_inherit = 'mail.compose.message'
_description = 'Email composition wizard for Survey'
_log_access = True
def _get_public_url(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
res = dict((id, 0) for id in ids)
survey_obj = self.pool.get('survey')
for wizard in self.browse(cr, uid, ids, context=context):
res[wizard.id] = survey_obj.browse(cr, uid, wizard.survey_id, context=context).public_url
return res
def _get_public_url_html(self, cr, uid, ids, name, arg, context=None):
""" Compute if the message is unread by the current user. """
urls = self._get_public_url(cr, uid, ids, name, arg, context=context)
for key, url in urls.items():
urls[key] = '<a href="%s">%s</a>' % (url, _("Click here to take survey"))
return urls
_columns = {
'survey_id': fields.many2one('survey', 'Survey', required=True),
'public': fields.selection([('public_link', 'Share the public web link to your audience.'), \
('email_public_link', 'Send by email the public web link to your audience.'),\
('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')],
string='Share options', required=True),
'public_url': fields.function(_get_public_url, string="Public url", type="char"),
'public_url_html': fields.function(_get_public_url_html, string="Public HTML web link", type="char"),
'partner_ids': fields.many2many('res.partner',
'survey_mail_compose_message_res_partner_rel',
'wizard_id', 'partner_id', 'Existing contacts'),
'attachment_ids': fields.many2many('ir.attachment',
'survey_mail_compose_message_ir_attachments_rel',
'wizard_id', 'attachment_id', 'Attachments'),
'multi_email': fields.text(string='List of emails', help="This list of emails of recipients will not converted in contacts. Emails separated by commas, semicolons or newline."),
'date_deadline': fields.date(string="Deadline to which the invitation to respond is valid", help="Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid."),
}
_defaults = {
'public': 'email_private',
'survey_id': lambda self,cr,uid,ctx={}: ctx.get('model') == 'survey' and ctx.get('res_id') or None,
}
def default_get(self, cr, uid, fields, context=None):
res = super(survey_mail_compose_message, self).default_get(cr, uid, fields, context=context)
if context.get('active_model') == 'res.partner' and context.get('active_ids'):
res.update({'partner_ids': context.get('active_ids')})
return res
def onchange_multi_email(self, cr, uid, ids, multi_email, context=None):
emails = list(set(emails_split.split(multi_email or "")))
emails_checked = []
error_message = ""
for email in emails:
email = email.strip()
if email:
if not re.search(r"^[^@]+@[^@]+$", email):
error_message += "\n'%s'" % email
else:
emails_checked.append(email)
if error_message:
raise osv.except_osv(_('Warning!'), _("One email at least is incorrect: %s" % error_message))
emails_checked.sort()
values = {'multi_email': '\n'.join(emails_checked)}
return {'value': values}
def onchange_survey_id(self, cr, uid, ids, survey_id, context=None):
""" Compute if the message is unread by the current user. """
if survey_id:
survey = self.pool.get('survey').browse(cr, uid, survey_id, context=context)
return {
'value': {
'subject': survey.title,
'public_url': survey.public_url,
'public_url_html': '<a href="%s">%s</a>' % (survey.public_url, _("Click here to take survey")),
}}
else:
txt = _("Please select a survey")
return {
'value': {
'public_url': txt,
'public_url_html': txt,
}}
#------------------------------------------------------
# Wizard validation and send
#------------------------------------------------------
def send_mail(self, cr, uid, ids, context=None):
""" Process the wizard content and proceed with sending the related
email(s), rendering any template patterns on the fly if needed. """
if context is None:
context = {}
survey_response_obj = self.pool.get('survey.response')
partner_obj = self.pool.get('res.partner')
mail_mail_obj = self.pool.get('mail.mail')
try:
model, anonymous_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_anonymous')
except ValueError:
anonymous_id = None
def create_response_and_send_mail(wizard, token, partner_id, email):
""" Create one mail by recipients and replace __URL__ by link with identification token
"""
#set url
url = token and re.sub(r'params=[^&]+', 'params=%s' % token, wizard.survey_id.public_url) or wizard.survey_id.public_url
# post the message
values = {
'model': None,
'res_id': None,
'subject': wizard.subject,
'body': wizard.body.replace("__URL__", url),
'body_html': wizard.body.replace("__URL__", url),
'parent_id': None,
'partner_ids': partner_id and [(4, partner_id)] or None,
'notified_partner_ids': partner_id and [(4, partner_id)] or None,
'attachment_ids': wizard.attachment_ids or None,
'email_from': wizard.email_from or None,
'email_to': email,
}
mail_id = mail_mail_obj.create(cr, uid, values, context=context)
mail_mail_obj.send(cr, uid, [mail_id], context=context)
def create_token(wizard, partner_id, email):
if context.get("survey_resent_token"):
response_ids = survey_response_obj.search(cr, uid, [('survey_id', '=', wizard.survey_id.id), ('state', 'in', ['new', 'skip']), '|', ('partner_id', '=', partner_id), ('email', '=', email)], context=context)
if response_ids:
return survey_response_obj.read(cr, uid, response_ids, ['token'], context=context)[0]['token']
if wizard.public != 'email_private':
return None
else:
token = uuid.uuid4()
# create response with token
survey_response_obj.create(cr, uid, {
'date_deadline': wizard.date_deadline,
'survey_id': wizard.survey_id.id,
'date_create': datetime.now(),
'response_type': 'link',
'state': 'new',
'token': token,
'partner_id': partner_id,
'email': email,
})
return token
for wizard in self.browse(cr, uid, ids, context=context):
# check if __URL__ is in the text
if wizard.body.find("__URL__") < 0:
raise osv.except_osv(_('Warning!'), _("The content of the text don't contain '__URL__'. \
__URL__ is automaticaly converted into the special url of the survey."))
if not wizard.multi_email and not wizard.partner_ids and (context.get('default_partner_ids') or context.get('default_multi_email')):
wizard.multi_email = context.get('default_multi_email')
wizard.partner_ids = context.get('default_partner_ids')
# quick check of email list
emails_list = []
if wizard.multi_email:
emails = list(set(emails_split.split(wizard.multi_email)) - set([partner.email for partner in wizard.partner_ids]))
for email in emails:
email = email.strip()
if re.search(r"^[^@]+@[^@]+$", email):
emails_list.append(email)
# remove public anonymous access
partner_list = []
for partner in wizard.partner_ids:
if not anonymous_id or not partner.user_ids or anonymous_id not in [x.id for x in partner.user_ids[0].groups_id]:
partner_list.append({'id': partner.id, 'email': partner.email})
if not len(emails_list) and not len(partner_list):
if wizard.model == 'res.partner' and wizard.res_id:
return False
raise osv.except_osv(_('Warning!'), _("Please enter at least one valid recipient."))
for email in emails_list:
partner_id = partner_obj.search(cr, uid, [('email', '=', email)], context=context)
partner_id = partner_id and partner_id[0] or None
token = create_token(wizard, partner_id, email)
create_response_and_send_mail(wizard, token, partner_id, email)
for partner in partner_list:
token = create_token(wizard, partner['id'], partner['email'])
create_response_and_send_mail(wizard, token, partner['id'], partner['email'])
return {'type': 'ir.actions.act_window_close'}

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--Survey send invitation Email template -->
<record id="email_template_survey" model="email.template">
<field name="name">Survey - Send by Email</field>
<field name="model_id" ref="model_survey"/>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); ">
<p>Hello,</p>
<p>We are conducting a survey, and you response would be appreciated.</p>
<p><a href="__URL__">Please, click here to take survey</a></p>
<p>Thanks for your participation!</p>
</div>
]]></field>
</record>
<!-- Replace the default mass-mailing wizard in base with the composition wizard -->
<act_window name="Partner Survey Mailing"
res_model="survey.mail.compose.message"
src_model="res.partner"
view_mode="form"
multi="True"
target="new"
key2="client_action_multi"
id="survey.action_partner_survey_mail"
context="{
'default_use_template': True,
'default_template_id': ref('email_template_survey'),
}"/>
<!--Survey send
Context['survey_resent_token'], if True, hidde share option, emails list and partner_ids
-->
<record model="ir.ui.view" id="survey_email_compose_message">
<field name="name">survey.mail.compose.message.form</field>
<field name="model">survey.mail.compose.message</field>
<field name="arch" type="xml">
<form string="Compose Email" version="7.0">
<field name="composition_mode" invisible="1"/>
<field name="model" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="parent_id" invisible="1"/>
<group col="2">
<field name="survey_id" readonly="context.get('default_survey_id')" on_change="onchange_survey_id(survey_id)"/>
<field name="public" widget="radio" invisible="context.get('survey_resent_token')"/>
</group>
<group col="1" invisible="context.get('survey_resent_token')" attrs="{'invisible':[('public','in',['email_private', 'email_public_link'])]}" class="oe_survey_email_public">
<div>
You can share your survey web public link and/or send private invitations to your audience.<br/>
People can response once per invitation, and whenever they want with the public web link.
</div>
<div class="oe_survey_url_label">Copy, paste and share the web link below to your audience.</div>
<div class="oe_survey_url">
<field name="public_url"/>
</div>
<div class="oe_survey_url_label">Copy and paste the HTML code below to add this web link to any webpage.</div>
<div class="oe_survey_url">
<field name="public_url_html"/>
</div>
</group>
<group col="1" attrs="{'invisible':['|',('public','=',False),('public','in',['public_link'])]}">
<group col="2">
<field invisible="context.get('survey_resent_token')" name="partner_ids" widget="many2many_tags_email" placeholder="Add list of existing contacts..." context="{'force_email':True, 'show_email':True}"/>
<field invisible="context.get('survey_resent_token')" name="multi_email" placeholder="Add list of email of recipients (will not converted in partner), separated by commas, semicolons or newline..." on_change="onchange_multi_email(multi_email)" no_resize="1"/>
<field name="subject" placeholder="Subject..."/>
</group>
<field name="body" help="__URL__ will be automatically transformed into web address (public or private, depending on your choice). You can click on 'Show Source' button to see __URL__ in the link tag on the email template."/>
<group col="2">
<div>
<label for="attachment_ids"/>
<field name="attachment_ids" widget="many2many_binary"/>
</div>
<div class="oe_survey_date_deadline">
<label for="date_deadline"/>
<field name="date_deadline"/>
</div>
</group>
</group>
<footer attrs="{'invisible':[('public','in',['email_private', 'email_public_link'])]}">
<button string="Close" class="oe_link" special="cancel" />
</footer>
<footer attrs="{'invisible':['|',('public','=',False),('public','in',['public_link'])]}">
<button string="Send" name="send_mail" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
<group class="oe_right" col="1">
<div>Use template
<field name="template_id" nolabel="1"
on_change="onchange_template_id(template_id, composition_mode, model, res_id, context)"/>
</div>
<button icon="/email_template/static/src/img/email_template_save.png"
type="object" name="save_as_template" string="Save as new template" class="oe_link"
help="Save as a new template"/>
</group>
</footer>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -9,6 +9,11 @@
<field name="model">survey.print</field>
<field name="arch" type="xml">
<form string="Survey Print" version="7.0">
<header>
<button name="action_next" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<group col="4">
<separator string="Survey" colspan="4"/>
<field name="survey_ids" nolabel="1" colspan="4" />
@ -18,11 +23,6 @@
<field name="page_number" colspan="4"/>
<field name="without_pagebreak" colspan="4"/>
</group>
<footer>
<button name="action_next" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
@ -39,7 +39,7 @@
<menuitem name="Print Surveys" id="menu_print_survey_form" sequence="1"
action="action_view_survey_print" parent="base.next_id_10"
groups="base.group_tool_manager" icon="STOCK_PRINT"/>
groups="base.group_survey_manager" icon="STOCK_PRINT"/>
</data>
</openerp>

View File

@ -20,7 +20,7 @@
##############################################################################
from openerp.osv import fields, osv
from openerp.tools.translate import _
class survey_print_answer(osv.osv_memory):
_name = 'survey.print.answer'
@ -37,10 +37,10 @@ class survey_print_answer(osv.osv_memory):
}
_defaults = {
'orientation': lambda *a:'vertical',
'paper_size': lambda *a:'letter',
'page_number': lambda *a: 0,
'without_pagebreak': lambda *a: 0
'orientation': 'vertical',
'paper_size': 'letter',
'page_number': 0,
'without_pagebreak': 0
}
def action_next(self, cr, uid, ids, context=None):
@ -57,8 +57,7 @@ class survey_print_answer(osv.osv_memory):
if context is None:
context = {}
datas = {'ids': context.get('active_ids', [])}
res = self.read(cr, uid, ids, ['response_ids', 'orientation', 'paper_size',\
'page_number', 'without_pagebreak'], context=context)
res = self.read(cr, uid, ids, ['response_ids', 'orientation', 'paper_size', 'page_number', 'without_pagebreak'], context=context)
res = res and res[0] or {}
datas['form'] = res
datas['model'] = 'survey.print.answer'

View File

@ -9,6 +9,11 @@
<field name="model">survey.print.answer</field>
<field name="arch" type="xml">
<form string="Print Answer" version="7.0">
<header>
<button name="action_next" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<group col="4">
<separator string="Answer" colspan="4"/>
<field name="response_ids" nolabel="1" colspan="4" />
@ -18,11 +23,6 @@
<field name="page_number" colspan="4"/>
<field name="without_pagebreak" colspan="4"/>
</group>
<footer>
<button name="action_next" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
@ -39,7 +39,10 @@
</record>
<menuitem name="Surveys Answers" action="action_view_survey_print_answer" id="menu_print_survey_answer"
parent="base.next_id_10" icon="STOCK_PRINT" groups="base.group_tool_manager"/>
parent="base.next_id_10" icon="STOCK_PRINT" groups="base.group_survey_manager"/>
<menuitem name="Surveys All Responses" action="action_view_survey_print_answer" id="menu_print_survey_answer"
parent="menu_reporting" sequence="2"/>
</data>
</openerp>

View File

@ -39,6 +39,7 @@ class survey_print_statistics(osv.osv_memory):
res = res and res[0] or {}
datas['form'] = res
datas['model'] = 'survey.print.statistics'
print datas
return {
'type': 'ir.actions.report.xml',
'report_name': 'survey.analysis',

View File

@ -9,12 +9,12 @@
<field name="model">survey.print.statistics</field>
<field name="arch" type="xml">
<form string="Survey Print Statistics" version="7.0">
<field name="survey_ids"/>
<footer>
<header>
<button name="action_next" string="Print" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</header>
<field name="survey_ids"/>
</form>
</field>
</record>
@ -31,7 +31,10 @@
</record>
<menuitem name="Surveys Statistics" action="action_view_survey_print_statistics" id="menu_print_survey_statistics"
parent="base.next_id_10" icon="STOCK_PRINT" groups="base.group_tool_manager"/>
parent="base.next_id_10" icon="STOCK_PRINT" groups="base.group_survey_manager"/>
<menuitem name="Surveys Statistics" action="action_view_survey_print_statistics" id="menu_survey_print_survey_statistics"
parent="menu_reporting" sequence="3"/>
</data>
</openerp>

View File

@ -1,105 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from lxml import etree
from openerp.osv import fields, osv
from openerp.tools.translate import _
class survey_name_wiz(osv.osv_memory):
_name = 'survey.name.wiz'
_columns = {
'survey_id': fields.many2one('survey', 'Survey', required=True, ondelete='cascade', domain= [('state', '=', 'open')]),
'page_no': fields.integer('Page Number'),
'note': fields.text("Description"),
'page': fields.char('Page Position',size = 12),
'transfer': fields.boolean('Page Transfer'),
'store_ans': fields.text('Store Answer'),
'response': fields.char('Answer',size=16)
}
_defaults = {
'page_no': -1,
'page': 'next',
'transfer': 1,
'response': 0,
'survey_id': lambda self,cr,uid,context:context.get('survey_id',False),
'store_ans': '{}' #Setting the default pattern as '{}' as the field is of type text. The field always gets the value in dict format
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(survey_name_wiz, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
if uid != 1:
survey_obj = self.pool.get('survey')
line_ids = survey_obj.search(cr, uid, [('invited_user_ids','in',uid)], context=context)
domain = str([('id', 'in', line_ids)])
doc = etree.XML(res['arch'])
nodes = doc.xpath("//field[@name='survey_id']")
for node in nodes:
node.set('domain', domain)
res['arch'] = etree.tostring(doc)
return res
def action_next(self, cr, uid, ids, context=None):
"""
Start the survey, Increment in started survey field but if set the max_response_limit of
survey then check the current user how many times start this survey. if current user max_response_limit
is reach then this user can not start this survey(Raise Exception).
"""
survey_obj = self.pool.get('survey')
search_obj = self.pool.get('ir.ui.view')
if context is None: context = {}
this = self.browse(cr, uid, ids, context=context)[0]
survey_id = this.survey_id.id
context.update({'survey_id': survey_id, 'sur_name_id': this.id})
cr.execute('select count(id) from survey_history where user_id=%s\
and survey_id=%s' % (uid,survey_id))
res = cr.fetchone()[0]
sur_rec = survey_obj.browse(cr,uid,survey_id,context=context)
if sur_rec.response_user and res >= sur_rec.response_user:
raise osv.except_osv(_('Warning!'),_("You cannot give response for this survey more than %s times.") % (sur_rec.response_user))
if sur_rec.max_response_limit and sur_rec.max_response_limit <= sur_rec.tot_start_survey:
raise osv.except_osv(_('Warning!'),_("You cannot give more responses. Please contact the author of this survey for further assistance."))
search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.question.wiz',
'type': 'ir.actions.act_window',
'target': 'new',
'search_view_id': search_id[0],
'context': context
}
def on_change_survey(self, cr, uid, ids, survey_id, context=None):
"""
on change event of survey_id field, if note is available in selected survey then display this note in note fields.
"""
if not survey_id:
return {}
notes = self.pool.get('survey').read(cr, uid, survey_id, ['note'])['note']
return {'value': {'note': notes}}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,36 +0,0 @@
<?xml version="1.0" ?>
<openerp>
<data>
<!--
Display Survey List
-->
<record id="view_survey_name" model="ir.ui.view">
<field name="name">Survey</field>
<field name="model">survey.name.wiz</field>
<field name="arch" type="xml">
<form string="Survey" version="7.0">
<group>
<field name="survey_id" on_change="on_change_survey(survey_id)"/>
</group>
<field name="note" placeholder="Add Description" attrs="{'readonly': [('survey_id','=',False)]}"/>
<footer>
<button name="action_next" string="Start" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_view_survey_name"
model="ir.actions.act_window">
<field name="name">Give Survey Answer</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">survey.name.wiz</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -1,240 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
import time
from random import choice
import string
import os
import datetime
import socket
from openerp import tools
from openerp.modules.module import get_module_resource
from openerp.osv import fields, osv
import openerp.report
from openerp.tools.translate import _
class survey_send_invitation(osv.osv_memory):
_name = 'survey.send.invitation'
_columns = {
'partner_ids': fields.many2many('res.partner','survey_res_partner','partner_id',\
'survey_id', "Answer", required=1),
'send_mail': fields.boolean('Send Mail for New User'),
'send_mail_existing': fields.boolean('Send Reminder for Existing User'),
'mail_subject': fields.char('Subject', size=256),
'mail_subject_existing': fields.char('Subject', size=256),
'mail_from': fields.char('From', size=256, required=1),
'mail': fields.text('Body')
}
_defaults = {
'send_mail': lambda *a: 1,
'send_mail_existing': lambda *a: 1,
}
def genpasswd(self):
chars = string.letters + string.digits
return ''.join([choice(chars) for i in range(6)])
def default_get(self, cr, uid, fields_list, context=None):
if context is None:
context = {}
data = super(survey_send_invitation, self).default_get(cr, uid, fields_list, context)
survey_obj = self.pool.get('survey')
msg = ""
name = ""
for sur in survey_obj.browse(cr, uid, context.get('active_ids', []), context=context):
name += "\n --> " + sur.title + "\n"
if sur.state != 'open':
msg += sur.title + "\n"
data['mail_subject'] = _("Invitation for %s") % (sur.title)
data['mail_subject_existing'] = _("Invitation for %s") % (sur.title)
data['mail_from'] = sur.responsible_id.email
if msg:
raise osv.except_osv(_('Warning!'), _('The following surveys are not in open state: %s') % msg)
data['mail'] = _('''
Hello %%(name)s, \n\n
Would you please spent some of your time to fill-in our survey: \n%s\n
You can access this survey with the following parameters:
URL: %s
Your login ID: %%(login)s\n
Your password: %%(passwd)s\n
\n\n
Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context))
return data
def create_report(self, cr, uid, res_ids, report_name=False, file_name=False):
if not report_name or not res_ids:
return (False, Exception('Report name and Resources ids are required !!!'))
try:
ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf'
result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, {})
fp = open(ret_file_name, 'wb+');
fp.write(result);
fp.close();
except Exception,e:
print 'Exception in create report:',e
return (False, str(e))
return (True, ret_file_name)
def action_send(self, cr, uid, ids, context=None):
if context is None:
context = {}
record = self.read(cr, uid, ids, [],context=context)
survey_ids = context.get('active_ids', [])
record = record and record[0]
partner_ids = record['partner_ids']
user_ref= self.pool.get('res.users')
survey_ref= self.pool.get('survey')
mail_message = self.pool.get('mail.message')
model_data_obj = self.pool.get('ir.model.data')
group_id = model_data_obj._get_id(cr, uid, 'base', 'group_survey_user')
group_id = model_data_obj.browse(cr, uid, group_id, context=context).res_id
act_id = self.pool.get('ir.actions.act_window')
act_id = act_id.search(cr, uid, [('res_model', '=' , 'survey.name.wiz'), \
('view_type', '=', 'form')])
out = "login,password\n"
skipped = 0
existing = ""
created = ""
error = ""
new_user = []
attachments = {}
current_sur = survey_ref.browse(cr, uid, context.get('active_id'), context=context)
exist_user = current_sur.invited_user_ids
if exist_user:
for use in exist_user:
new_user.append(use.id)
for id in survey_ref.browse(cr, uid, survey_ids):
report = self.create_report(cr, uid, [id.id], 'report.survey.form', id.title)
file = open(get_module_resource('survey', 'report') + id.title +".pdf")
file_data = ""
while 1:
line = file.readline()
file_data += line
if not line:
break
file.close()
attachments[id.title +".pdf"] = file_data
os.remove(get_module_resource('survey', 'report') + id.title +".pdf")
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids):
if not partner.email:
skipped+= 1
continue
user = user_ref.search(cr, uid, [('login', "=", partner.email)])
if user:
if user[0] not in new_user:
new_user.append(user[0])
user = user_ref.browse(cr, uid, user[0])
user_ref.write(cr, uid, user.id, {'survey_id':[[6, 0, survey_ids]]})
mail = record['mail']%{'login':partner.email, 'passwd':user.password, \
'name' : partner.name}
if record['send_mail_existing']:
vals = {
'state': 'outgoing',
'subject': record['mail_subject_existing'],
'body_html': '<pre>%s</pre>' % mail,
'email_to': partner.email,
'email_from': record['mail_from'],
}
self.pool.get('mail.mail').create(cr, uid, vals, context=context)
existing+= "- %s (Login: %s, Password: %s)\n" % (user.name, partner.email, \
user.password)
continue
passwd= self.genpasswd()
out+= partner.email + ',' + passwd + '\n'
mail= record['mail'] % {'login' : partner.email, 'passwd' : passwd, 'name' : partner.name}
if record['send_mail']:
vals = {
'state': 'outgoing',
'subject': record['mail_subject'],
'body_html': '<pre>%s</pre>' % mail,
'email_to': partner.email,
'email_from': record['mail_from'],
}
if attachments:
vals['attachment_ids'] = [(0,0,{'name': a_name,
'datas_fname': a_name,
'datas': str(a_content).encode('base64')})
for a_name, a_content in attachments.items()]
ans = self.pool.get('mail.mail').create(cr, uid, vals, context=context)
if ans:
res_data = {'name': partner.name or _('Unknown'),
'login': partner.email,
'password': passwd,
'address_id': partner.id,
'groups_id': [[6, 0, [group_id]]],
'action_id': act_id[0],
'survey_id': [[6, 0, survey_ids]]
}
create_ctx = dict(context, no_reset_password=True)
user = user_ref.create(cr, uid, res_data, context=create_ctx)
if user not in new_user:
new_user.append(user)
created+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
partner.email, passwd)
else:
error+= "- %s (Login: %s, Password: %s)\n" % (partner.name or _('Unknown'),\
partner.email, passwd)
new_vals = {}
new_vals.update({'invited_user_ids':[[6,0,new_user]]})
survey_ref.write(cr, uid, context.get('active_id'),new_vals)
note= ""
if created:
note += 'Created users:\n%s\n\n' % (created)
if existing:
note +='Already existing users:\n%s\n\n' % (existing)
if skipped:
note += "%d contacts where ignored (an email address is missing).\n\n" % (skipped)
if error:
note += 'Email not send successfully:\n====================\n%s\n' % (error)
context.update({'note' : note})
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.send.invitation.log',
'type': 'ir.actions.act_window',
'target': 'new',
'context': context
}
class survey_send_invitation_log(osv.osv_memory):
_name = 'survey.send.invitation.log'
_columns = {
'note' : fields.text('Log', readonly=1)
}
def default_get(self, cr, uid, fields_list, context=None):
if context is None:
context = {}
data = super(survey_send_invitation_log, self).default_get(cr, uid, fields_list, context)
data['note'] = context.get('note', '')
return data
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,74 +0,0 @@
<?xml version="1.0" ?>
<openerp>
<data>
<!-- Survey send invitation Form View -->
<record id="view_survey_send_invitation" model="ir.ui.view">
<field name="name">Send Invitation</field>
<field name="model">survey.send.invitation</field>
<field name="arch" type="xml">
<form string="Send Invitation" version="7.0">
<group col="4">
<separator string="Select Partner" colspan="4"/>
<field name="partner_ids" nolabel="1" colspan="4" widget="many2many_tags"/>
<separator colspan="4" string="Send Mail for New User"/>
<field name="send_mail" nolabel="1"/>
<field name="mail_subject" colspan="3"/>
<separator colspan="4" string="Send Reminder for Existing User"/>
<field name="send_mail_existing" nolabel="1"/>
<field name="mail_subject_existing" colspan="3"/>
<separator colspan="4"/>
<field name="mail_from" colspan="4"/>
<separator string="Message" colspan="4"/>
<field name="mail" nolabel="1" colspan="4"/>
</group>
<footer>
<button name="action_send" string="_Send" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<!-- Survey send invitation action -->
<record id="action_view_survey_send_invitation" model="ir.actions.act_window">
<field name="name">Send Invitation</field>
<field name="res_model">survey.send.invitation</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<act_window id="action_act_view_survey_send_invitation"
key2="client_action_multi" name="Send Invitations"
res_model="survey.send.invitation" src_model="survey"
view_mode="form" target="new" view_type="form" />
<!-- Survey send invitation Display Log Form View -->
<record id="view_survey_send_invitation_log" model="ir.ui.view">
<field name="name">survey send invitation log</field>
<field name="model">survey.send.invitation.log</field>
<field name="arch" type="xml">
<form string="User creation" version="7.0">
<group string="Results :">
<field name="note"/>
</group>
</form>
</field>
</record>
<!-- Survey send invitation action -->
<record id="action_view_survey_send_invitation_log" model="ir.actions.act_window">
<field name="name">survey.send.invitation.log</field>
<field name="res_model">survey.send.invitation.log</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import survey

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Survey CRM',
'version': '0.1',
'category': 'Tools',
'complexity': 'easy',
'description': """
This module adds a survey mass mailing button inside the more option of lead view
=================================================================================
""",
'author': 'OpenERP SA',
'depends': ['crm', 'survey'],
'data': [
'crm_view.xml',
],
'installable': True,
'auto_install': True,
'category': 'Hidden',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Replace the default mass-mailing wizard in base with the composition wizard -->
<act_window name="Partner Survey Mailing"
res_model="survey.mail.compose.message"
src_model="crm.lead"
view_mode="form"
multi="True"
target="new"
key2="client_action_multi"
id="survey.action_partner_survey_mail_crm"
context="{
'default_use_template': True,
'default_template_id': ref('survey.email_template_survey'),
}"/>
</data>
</openerp>

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import osv
class survey_mail_compose_message(osv.TransientModel):
_inherit = 'survey.mail.compose.message'
def default_get(self, cr, uid, fields, context=None):
res = super(survey_mail_compose_message, self).default_get(cr, uid, fields, context=context)
if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
partner_ids = []
emails_list = []
for lead in self.pool.get('crm.lead').browse(cr, uid, context.get('active_ids'), context=context):
if lead.partner_id:
partner_ids.append(lead.partner_id.id)
else:
email = lead.contact_name and "%s <%s>" % (lead.contact_name, lead.email_from or "") or lead.email_from or None
if email and email not in emails_list:
emails_list.append(email)
multi_email = "\n".join(emails_list)
res.update({'partner_ids': list(set(partner_ids)), 'multi_email': multi_email})
return res