Browse Source

[REF] for myceliandre addons

12.0
RemiFr82 1 year ago
parent
commit
83efbf8951
  1. 60
      survey_custom_matrix/__manifest__.py
  2. 2
      survey_custom_matrix/controllers/__init__.py
  3. 78
      survey_custom_matrix/controllers/main.py
  4. 146
      survey_custom_matrix/controllers/survey.py
  5. 18
      survey_custom_matrix/models/survey_label.py
  6. 2
      survey_custom_matrix/models/survey_label_value.py
  7. 16
      survey_custom_matrix/models/survey_question.py
  8. 177
      survey_custom_matrix/models/survey_user_input_line.py
  9. 59
      survey_deadline_autoclose/__manifest__.py
  10. 4
      survey_deadline_autoclose/data/ir_cron.xml
  11. 4
      survey_deadline_autoclose/i18n/fr.po
  12. 71
      survey_deadline_autoclose/models/survey_survey.py
  13. 2
      survey_deadline_autoclose/views/survey_survey.xml
  14. 57
      survey_description/__manifest__.py
  15. 2
      survey_description/i18n/fr.po
  16. 61
      survey_input_attachment/__manifest__.py
  17. 24
      survey_input_attachment/i18n/fr.po
  18. 28
      survey_input_attachment/models/survey_question.py
  19. 82
      survey_input_attachment/models/survey_user_input_line.py
  20. 55
      survey_input_dates/__manifest__.py
  21. 12
      survey_input_dates/i18n/fr.po
  22. 42
      survey_input_dates/models/survey_user_input.py
  23. 3
      survey_input_dates/views/survey_user_input.xml
  24. 55
      survey_input_odoo_debrand/__manifest__.py
  25. 63
      survey_input_template_custom/__manifest__.py
  26. 55
      survey_link_input_ratio/__manifest__.py
  27. 88
      survey_link_input_ratio/models/survey_survey.py
  28. 24
      survey_link_input_ratio/views/survey_survey.xml
  29. 57
      survey_partner_input/__manifest__.py
  30. 92
      survey_partner_input/models/res_partner.py
  31. 55
      survey_question_duplicate/__manifest__.py
  32. 57
      survey_select_input/__manifest__.py
  33. 55
      survey_template/__manifest__.py
  34. 56
      survey_template/models/survey_survey.py

60
survey_custom_matrix/__manifest__.py

@ -1,28 +1,42 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': "Survey custom matrix",
'version': '1.0',
'summary': 'This app allows handling of complex survey forms with options like multiple choice questions, custom matrix etc.',
'description': """
Custom Matrix Survey.
================================
"name": "Survey Custom Matrix",
"version": "1.0.0",
"summary": """
This app allows handling of complex survey forms with options like multiple choice questions, custom matrix etc.
""", """,
'license': 'OPL-1',
'author': "Kanak Infosystems LLP.",
'website': "http://www.kanakinfosystems.com",
'images': ['static/description/banner.jpg'],
'category': 'Website',
'depends': ['survey'],
'data': [
'security/ir_model_access.xml',
'templates/matrix.xml',
'reports/user_input.xml',
'views/survey_question.xml',
'views/survey_user_input.xml',
'views/survey_user_input_line.xml',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'application': True,
# 'price': 49,
# 'currency': 'EUR',
"data": [
"security/ir_model_access.xml",
"templates/matrix.xml",
"reports/user_input.xml",
"views/survey_question.xml",
"views/survey_user_input.xml",
"views/survey_user_input_line.xml",
],
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

2
survey_custom_matrix/controllers/__init__.py

@ -1,2 +1,2 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from . import main
from . import survey

78
survey_custom_matrix/controllers/main.py

@ -1,78 +0,0 @@
# -*- coding: utf-8 -*-
import json
from odoo import http
from odoo.http import request
from odoo.addons.survey.controllers.main import Survey
import logging
_logger = logging.getLogger(__name__)
class Survey(Survey):
@http.route([
'/survey/prefill/<model("survey.survey"):survey>/<string:token>',
'/survey/prefill/<model("survey.survey"):survey>/<string:token>/<model("survey.page"):page>'],
type='http', auth='public', website=True)
def prefill(self, survey, token, page=None, **post):
UserInputLine = request.env['survey.user_input_line']
ret = {}
# Fetch previous answers
if page:
previous_answers = UserInputLine.sudo().search([('user_input_id.token', '=', token), ('page_id', '=', page.id)])
else:
previous_answers = UserInputLine.sudo().search([('user_input_id.token', '=', token)])
# Return non empty answers in a JSON compatible format
for answer in previous_answers:
if not answer.skipped:
answer_tag = '%s_%s_%s' % (answer.survey_id.id, answer.page_id.id, answer.question_id.id)
answer_value = None
if answer.question_id.matrix_subtype == 'custom':
if answer.answer_type == 'free_text':
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_free_text
elif answer.answer_type == 'text':
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_text
elif answer.answer_type == 'number':
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = str(answer.value_number)
elif answer.answer_type == 'date':
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_date
elif answer.answer_type == 'dropdown':
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_id.id
elif answer.answer_type == 'suggestion' and not answer.value_suggested_row:
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_suggested.id
elif answer.answer_type == 'suggestion' and answer.value_suggested_row:
answer_tag = "%s_%s_%s" % (answer_tag, answer.value_suggested_row.id, answer.value_suggested.id)
answer_value = answer.value_suggested.id
if answer_value:
ret.setdefault(answer_tag, []).append(answer_value)
else:
_logger.warning("[survey] No answer has been found for question %s marked as non skipped" % answer_tag)
else:
if answer.answer_type == 'free_text':
answer_value = answer.value_free_text
elif answer.answer_type == 'text' and answer.question_id.type == 'textbox':
answer_value = answer.value_text
elif answer.answer_type == 'text' and answer.question_id.type != 'textbox':
# here come comment answers for matrices, simple choice and multiple choice
answer_tag = "%s_%s" % (answer_tag, 'comment')
answer_value = answer.value_text
elif answer.answer_type == 'number':
answer_value = str(answer.value_number)
elif answer.answer_type == 'date':
answer_value = answer.value_date
elif answer.answer_type == 'suggestion' and not answer.value_suggested_row:
answer_value = answer.value_suggested.id
elif answer.answer_type == 'suggestion' and answer.value_suggested_row:
answer_tag = "%s_%s" % (answer_tag, answer.value_suggested_row.id)
answer_value = answer.value_suggested.id
if answer_value:
ret.setdefault(answer_tag, []).append(answer_value)
else:
_logger.warning("[survey] No answer has been found for question %s marked as non skipped" % answer_tag)
return json.dumps(ret)

146
survey_custom_matrix/controllers/survey.py

@ -0,0 +1,146 @@
# -*- coding: utf-8 -*-
import json
from odoo import http
from odoo.http import request
from odoo.addons.survey.controllers.main import Survey
import logging
_logger = logging.getLogger(__name__)
class Survey(Survey):
@http.route(
[
'/survey/prefill/<model("survey.survey"):survey>/<string:token>',
'/survey/prefill/<model("survey.survey"):survey>/<string:token>/<model("survey.page"):page>',
],
type="http",
auth="public",
website=True,
)
def prefill(self, survey, token, page=None, **post):
UserInputLine = request.env["survey.user_input_line"]
ret = {}
# Fetch previous answers
if page:
previous_answers = UserInputLine.sudo().search(
[("user_input_id.token", "=", token), ("page_id", "=", page.id)]
)
else:
previous_answers = UserInputLine.sudo().search(
[("user_input_id.token", "=", token)]
)
# Return non empty answers in a JSON compatible format
for answer in previous_answers:
if not answer.skipped:
answer_tag = "%s_%s_%s" % (
answer.survey_id.id,
answer.page_id.id,
answer.question_id.id,
)
answer_value = None
if answer.question_id.matrix_subtype == "custom":
if answer.answer_type == "free_text":
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_free_text
elif answer.answer_type == "text":
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_text
elif answer.answer_type == "number":
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = str(answer.value_number)
elif answer.answer_type == "date":
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_date
elif answer.answer_type == "dropdown":
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_id.id
elif (
answer.answer_type == "suggestion"
and not answer.value_suggested_row
):
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_suggested.id
elif (
answer.answer_type == "suggestion"
and answer.value_suggested_row
):
answer_tag = "%s_%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
answer.value_suggested.id,
)
answer_value = answer.value_suggested.id
if answer_value:
ret.setdefault(answer_tag, []).append(answer_value)
else:
_logger.warning(
"[survey] No answer has been found for question %s marked as non skipped"
% answer_tag
)
else:
if answer.answer_type == "free_text":
answer_value = answer.value_free_text
elif (
answer.answer_type == "text"
and answer.question_id.type == "textbox"
):
answer_value = answer.value_text
elif (
answer.answer_type == "text"
and answer.question_id.type != "textbox"
):
# here come comment answers for matrices, simple choice and multiple choice
answer_tag = "%s_%s" % (answer_tag, "comment")
answer_value = answer.value_text
elif answer.answer_type == "number":
answer_value = str(answer.value_number)
elif answer.answer_type == "date":
answer_value = answer.value_date
elif (
answer.answer_type == "suggestion"
and not answer.value_suggested_row
):
answer_value = answer.value_suggested.id
elif (
answer.answer_type == "suggestion"
and answer.value_suggested_row
):
answer_tag = "%s_%s" % (
answer_tag,
answer.value_suggested_row.id,
)
answer_value = answer.value_suggested.id
if answer_value:
ret.setdefault(answer_tag, []).append(answer_value)
else:
_logger.warning(
"[survey] No answer has been found for question %s marked as non skipped"
% answer_tag
)
return json.dumps(ret)

18
survey_custom_matrix/models/survey_label.py

@ -2,17 +2,19 @@
from odoo import models, fields from odoo import models, fields
TYPES = [ TYPES = [
('free_text', 'Multiple Lines Text Box'),
('textbox', 'Single Line Text Box'),
('numerical_box', 'Numerical Value'),
("free_text", "Multiple Lines Text Box"),
("textbox", "Single Line Text Box"),
("numerical_box", "Numerical Value"),
# ('date', 'Date'), # ('date', 'Date'),
('dropdown', 'Dropdown'),
('checkbox', 'Checkbox'),
("dropdown", "Dropdown"),
("checkbox", "Checkbox"),
] ]
class SurveyLabel(models.Model): class SurveyLabel(models.Model):
_inherit = 'survey.label'
_inherit = "survey.label"
type = fields.Selection(selection=TYPES, string="Type of question", default="checkbox")
value_ids = fields.Many2many(comodel_name='survey.label.value', string="Values")
type = fields.Selection(
selection=TYPES, string="Type of question", default="checkbox"
)
value_ids = fields.Many2many(comodel_name="survey.label.value", string="Values")

2
survey_custom_matrix/models/survey_label_value.py

@ -3,7 +3,7 @@ from odoo import models, fields
class SurveyLabelValue(models.Model): class SurveyLabelValue(models.Model):
_name = 'survey.label.value'
_name = "survey.label.value"
_description = "Value" _description = "Value"
name = fields.Char(string="Name") name = fields.Char(string="Name")

16
survey_custom_matrix/models/survey_question.py

@ -4,9 +4,9 @@ from odoo.addons.survey.models.survey import dict_keys_startswith
class SurveyQuestion(models.Model): class SurveyQuestion(models.Model):
_inherit = 'survey.question'
_inherit = "survey.question"
matrix_subtype = fields.Selection(selection_add=[('custom', 'Custom Matrix')])
matrix_subtype = fields.Selection(selection_add=[("custom", "Custom Matrix")])
@api.multi @api.multi
def validate_matrix(self, post, answer_tag): def validate_matrix(self, post, answer_tag):
@ -15,14 +15,14 @@ class SurveyQuestion(models.Model):
if self.constr_mandatory: if self.constr_mandatory:
lines_number = len(self.labels_ids_2) lines_number = len(self.labels_ids_2)
answer_candidates = dict_keys_startswith(post, answer_tag) answer_candidates = dict_keys_startswith(post, answer_tag)
answer_candidates.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
answer_candidates.pop(("%s_%s" % (answer_tag, "comment")), "").strip()
# Number of lines that have been answered # Number of lines that have been answered
if self.matrix_subtype == 'simple':
if self.matrix_subtype == "simple":
answer_number = len(answer_candidates) answer_number = len(answer_candidates)
elif self.matrix_subtype == 'multiple':
answer_number = len({sk.rsplit('_', 1)[0] for sk in answer_candidates})
elif self.matrix_subtype == 'custom':
answer_number = len({sk.rsplit('_', 1)[0] for sk in answer_candidates})
elif self.matrix_subtype == "multiple":
answer_number = len({sk.rsplit("_", 1)[0] for sk in answer_candidates})
elif self.matrix_subtype == "custom":
answer_number = len({sk.rsplit("_", 1)[0] for sk in answer_candidates})
else: else:
raise RuntimeError("Invalid matrix subtype") raise RuntimeError("Invalid matrix subtype")
# Validate that each line has been answered # Validate that each line has been answered

177
survey_custom_matrix/models/survey_user_input_line.py

@ -4,119 +4,144 @@ from odoo.addons.survey.models.survey import dict_keys_startswith
class SurveyUserInputLine(models.Model): class SurveyUserInputLine(models.Model):
_inherit = 'survey.user_input_line'
_inherit = "survey.user_input_line"
answer_type = fields.Selection(selection_add=[('dropdown', 'Dropdown')], string='Answer Type')
matrix_subtype = fields.Selection(related='question_id.matrix_subtype')
value_id = fields.Many2one('survey.label.value', string="Value Dropdown")
answer_type = fields.Selection(
selection_add=[("dropdown", "Dropdown")], string="Answer Type"
)
matrix_subtype = fields.Selection(related="question_id.matrix_subtype")
value_id = fields.Many2one("survey.label.value", string="Value Dropdown")
@api.model @api.model
def save_line_matrix(self, user_input_id, question, post, answer_tag): def save_line_matrix(self, user_input_id, question, post, answer_tag):
vals = { vals = {
'user_input_id': user_input_id,
'question_id': question.id,
'survey_id': question.survey_id.id,
'skipped': False
"user_input_id": user_input_id,
"question_id": question.id,
"survey_id": question.survey_id.id,
"skipped": False,
} }
suil = self.search([
('user_input_id', '=', user_input_id),
('survey_id', '=', question.survey_id.id),
('question_id', '=', question.id)
])
suil = self.search(
[
("user_input_id", "=", user_input_id),
("survey_id", "=", question.survey_id.id),
("question_id", "=", question.id),
]
)
suil.sudo().unlink() suil.sudo().unlink()
no_answers = True no_answers = True
ca_dict = dict_keys_startswith(post, answer_tag + '_')
ca_dict = dict_keys_startswith(post, answer_tag + "_")
comment_answer = ca_dict.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
comment_answer = ca_dict.pop(("%s_%s" % (answer_tag, "comment")), "").strip()
if comment_answer: if comment_answer:
vals.update({
'answer_type': 'text',
'value_text': comment_answer,
})
vals.update(
{
"answer_type": "text",
"value_text": comment_answer,
}
)
self.create(vals) self.create(vals)
no_answers = False no_answers = False
if question.matrix_subtype == 'simple':
if question.matrix_subtype == "simple":
for row in question.labels_ids_2: for row in question.labels_ids_2:
a_tag = "%s_%s" % (answer_tag, row.id) a_tag = "%s_%s" % (answer_tag, row.id)
if a_tag in ca_dict: if a_tag in ca_dict:
no_answers = False no_answers = False
vals.update({
'answer_type': 'suggestion',
'value_suggested': ca_dict[a_tag],
'value_suggested_row': row.id,
})
vals.update(
{
"answer_type": "suggestion",
"value_suggested": ca_dict[a_tag],
"value_suggested_row": row.id,
}
)
self.create(vals) self.create(vals)
elif question.matrix_subtype == 'multiple':
elif question.matrix_subtype == "multiple":
for col in question.labels_ids: for col in question.labels_ids:
for row in question.labels_ids_2: for row in question.labels_ids_2:
a_tag = "%s_%s_%s" % (answer_tag, row.id, col.id) a_tag = "%s_%s_%s" % (answer_tag, row.id, col.id)
if a_tag in ca_dict: if a_tag in ca_dict:
no_answers = False no_answers = False
vals.update({
'answer_type': 'suggestion',
'value_suggested': col.id,
'value_suggested_row': row.id,
})
vals.update(
{
"answer_type": "suggestion",
"value_suggested": col.id,
"value_suggested_row": row.id,
}
)
self.create(vals) self.create(vals)
elif question.matrix_subtype == 'custom':
elif question.matrix_subtype == "custom":
for col in question.labels_ids: for col in question.labels_ids:
for row in question.labels_ids_2: for row in question.labels_ids_2:
a_tag = "%s_%s_%s" % (answer_tag, row.id, col.id) a_tag = "%s_%s_%s" % (answer_tag, row.id, col.id)
if a_tag in ca_dict: if a_tag in ca_dict:
no_answers = False no_answers = False
if post.get(a_tag): if post.get(a_tag):
sline = a_tag.split('_')[-1]
sline = a_tag.split("_")[-1]
label_obj = question.labels_ids.browse(int(sline)) label_obj = question.labels_ids.browse(int(sline))
if label_obj.type == 'textbox':
vals.update({
'answer_type': 'text',
'value_suggested': col.id,
'value_suggested_row': row.id,
'value_text': post.get(a_tag),
})
elif label_obj.type == 'free_text':
vals.update({
'answer_type': 'free_text',
'value_suggested': col.id,
'value_suggested_row': row.id,
'value_free_text': post.get(a_tag),
})
elif label_obj.type == 'numerical_box':
vals.update({
'answer_type': 'number',
'value_suggested': col.id,
'value_suggested_row': row.id,
'value_number': post.get(a_tag),
})
elif label_obj.type == 'date':
vals.update({
'answer_type': 'date',
'value_suggested': col.id,
'value_suggested_row': row.id,
'value_date': post.get(a_tag),
})
elif label_obj.type == 'dropdown':
vals.update({
'answer_type': 'dropdown',
'value_suggested': col.id,
'value_suggested_row': row.id,
'value_id': int(post.get(a_tag)),
})
if label_obj.type == "textbox":
vals.update(
{
"answer_type": "text",
"value_suggested": col.id,
"value_suggested_row": row.id,
"value_text": post.get(a_tag),
}
)
elif label_obj.type == "free_text":
vals.update(
{
"answer_type": "free_text",
"value_suggested": col.id,
"value_suggested_row": row.id,
"value_free_text": post.get(a_tag),
}
)
elif label_obj.type == "numerical_box":
vals.update(
{
"answer_type": "number",
"value_suggested": col.id,
"value_suggested_row": row.id,
"value_number": post.get(a_tag),
}
)
elif label_obj.type == "date":
vals.update(
{
"answer_type": "date",
"value_suggested": col.id,
"value_suggested_row": row.id,
"value_date": post.get(a_tag),
}
)
elif label_obj.type == "dropdown":
vals.update(
{
"answer_type": "dropdown",
"value_suggested": col.id,
"value_suggested_row": row.id,
"value_id": int(post.get(a_tag)),
}
)
else: else:
vals.update({
'answer_type': 'suggestion',
'value_suggested': col.id,
'value_suggested_row': row.id})
vals.update(
{
"answer_type": "suggestion",
"value_suggested": col.id,
"value_suggested_row": row.id,
}
)
self.create(vals) self.create(vals)
if no_answers: if no_answers:
vals.update({
'answer_type': None,
'skipped': True,
})
vals.update(
{
"answer_type": None,
"skipped": True,
}
)
self.create(vals) self.create(vals)
return True return True

59
survey_deadline_autoclose/__manifest__.py

@ -1,34 +1,39 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Auto-close survey on deadline',
'version': '1.0.0',
'summary': """
"name": "Auto-close survey on deadline",
"version": "1.0.0",
"summary": """
The module adds a deadline date on surveys and a checkbox to automatically close them with a planned action. The module adds a deadline date on surveys and a checkbox to automatically close them with a planned action.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'data/ir_cron.xml',
'data/mail_message_subtype.xml',
'views/survey_survey.xml',
"data": [
"data/ir_cron.xml",
"data/mail_message_subtype.xml",
"views/survey_survey.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

4
survey_deadline_autoclose/data/ir_cron.xml

@ -7,12 +7,12 @@
<field name="name">Close expired surveys</field> <field name="name">Close expired surveys</field>
<field name="model_id" ref="survey.model_survey_survey"/> <field name="model_id" ref="survey.model_survey_survey"/>
<field name="state">code</field> <field name="state">code</field>
<field name="code">model.action_close_survey()</field>
<field name="code">model.with_context(cron=True).close_deadline_survey()</field>
<field name="active" eval="True"/> <field name="active" eval="True"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field> <field name="interval_number">1</field>
<field name="interval_type">days</field> <field name="interval_type">days</field>
<field name="nextcall" eval="(datetime.today() + relativedelta(days=1)).strftime('%Y-%m-%d 00:10:00')"/>
<field name="nextcall" eval="(datetime.today() + relativedelta(days=1)).strftime('%Y-%m-%d 00:08:00')"/>
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall" eval="False"/> <field name="doall" eval="False"/>
</record> </record>

4
survey_deadline_autoclose/i18n/fr.po

@ -66,9 +66,9 @@ msgstr "Sondage"
#. module: survey_deadline_autoclose #. module: survey_deadline_autoclose
#: model:mail.message.subtype,description:survey_deadline_autoclose.mail_message_subtype_survey_expired #: model:mail.message.subtype,description:survey_deadline_autoclose.mail_message_subtype_survey_expired
msgid "This survey has expired." msgid "This survey has expired."
msgstr "Ce sondage a été clôturé."
msgstr "Ce sondage est arrivé à échéance."
#. module: survey_deadline_autoclose #. module: survey_deadline_autoclose
#: model:mail.message.subtype,description:survey_deadline_autoclose.mail_message_subtype_survey_closed #: model:mail.message.subtype,description:survey_deadline_autoclose.mail_message_subtype_survey_closed
msgid "This survey was closed." msgid "This survey was closed."
msgstr "Ce sondage est arrivé à échéance."
msgstr "Ce sondage a été clôturé."

71
survey_deadline_autoclose/models/survey_survey.py

@ -3,22 +3,33 @@ from odoo.exceptions import UserError
class SurveySurvey(models.Model): class SurveySurvey(models.Model):
_inherit = 'survey.survey'
_inherit = "survey.survey"
@api.model @api.model
def close_deadline_survey(self):
deadline = self.search([
('date_deadline', '!=', False),
('date_deadline', '<', fields.Date.today()),
])
to_close = deadline.filtered('auto_close')
def cron_close_deadline_survey(self):
deadline = self.search(
[
("date_deadline", "!=", False),
("date_deadline", "<", fields.Date.today()),
]
)
to_close = deadline.filtered("auto_close")
if to_close: if to_close:
to_close.action_close_survey() to_close.action_close_survey()
for survey in deadline - to_close: for survey in deadline - to_close:
survey.message_post(subtype='survey_deadline_autoclose.mail_message_subtype_survey_deadline')
survey.message_post(
subtype="survey_deadline_autoclose.mail_message_subtype_survey_deadline"
)
date_deadline = fields.Date(string="Deadline", copy=False, track_visibility='onchange')
auto_close = fields.Boolean(string="Auto close", default=False, help="If checked, the survey will be closed automatically when deadline is overpassed.", track_visibility='onchange')
date_deadline = fields.Date(
string="Deadline", copy=False, track_visibility="onchange"
)
auto_close = fields.Boolean(
string="Auto close",
default=False,
help="If checked, the survey will be automatically closed when deadline is overpassed.",
track_visibility="onchange",
)
# ACTIONS # ACTIONS
@ -26,25 +37,45 @@ class SurveySurvey(models.Model):
def action_send_survey(self): def action_send_survey(self):
self.ensure_one() self.ensure_one()
action = super(SurveySurvey, self).action_send_survey() action = super(SurveySurvey, self).action_send_survey()
action['context'].update({
'default_date_deadline': self.date_deadline,
})
action["context"].update(
{
"default_date_deadline": self.date_deadline,
}
)
return action return action
@api.multi @api.multi
def action_close_survey(self): def action_close_survey(self):
stage = self.env['survey.stage'].search([('closed', '=', True)], limit=1)
stage = self.env["survey.stage"].search([("closed", "=", True)], limit=1)
if not stage: if not stage:
raise UserError(_("No \"closed\" status found, the requested operation is impossible."))
self.write({
'stage_id': stage.id
})
if self.env.context.get("cron", False):
for survey in self: for survey in self:
survey.message_post(subtype='survey_deadline_autoclose.mail_message_subtype_survey_closed')
survey.message_post(
message_type="comment",
subject=_("Survey closing impossible"),
body=_(
'Survey should have been automatically closed but no "closed" '
"stage was found, the requested operation was impossible to proceed.\n"
'To fix this situation, you have to check "Closed" at least on one survey stage.'
),
)
else:
raise UserError(
_(
'No "closed" stage found, the requested operation is impossible.\n'
'To fix this situation, you have to check "Closed" at least on one survey stage.'
)
)
else:
self.write({"stage_id": stage.id})
for survey in self:
survey.message_post(
subtype="survey_deadline_autoclose.mail_message_subtype_survey_closed"
)
# ONCHANGES # ONCHANGES
@api.onchange('date_deadline')
@api.onchange("date_deadline")
def onchange_is_template(self): def onchange_is_template(self):
self.ensure_one() self.ensure_one()
if not self.date_deadline: if not self.date_deadline:

2
survey_deadline_autoclose/views/survey_survey.xml

@ -72,7 +72,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<search position="inside"> <search position="inside">
<group expand="0" string="Group By"> <group expand="0" string="Group By">
<filter string="Échéance" name="group_date_deadline" context="{'group_by':'date_deadline:month'}"/>
<filter string="Expiration month" name="group_date_deadline_month" context="{'group_by':'date_deadline:month'}"/>
</group> </group>
</search> </search>
</field> </field>

57
survey_description/__manifest__.py

@ -1,33 +1,38 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey description',
'version': '1.0.0',
'summary': """
"name": "Survey description",
"version": "1.0.0",
"summary": """
This module displays standard HTML fields \"Description\" and \"Thank you message\" on survey and survey pages. This module displays standard HTML fields \"Description\" and \"Thank you message\" on survey and survey pages.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_page.xml',
'views/survey_survey.xml',
"data": [
"views/survey_page.xml",
"views/survey_survey.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

2
survey_description/i18n/fr.po

@ -18,7 +18,7 @@ msgstr ""
#. module: survey_description #. module: survey_description
#: model_terms:ir.ui.view,arch_db:survey_description.survey_survey_form #: model_terms:ir.ui.view,arch_db:survey_description.survey_survey_form
msgid "Description" msgid "Description"
msgstr "Description"
msgstr ""
#. module: survey_description #. module: survey_description
#: model:ir.model,name:survey_description.model_survey_survey #: model:ir.model,name:survey_description.model_survey_survey

61
survey_input_attachment/__manifest__.py

@ -1,35 +1,40 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey input attachment',
'version': '1.0.0',
'summary': """
"name": "Survey input attachment",
"version": "1.0.0",
"summary": """
This module provides a new type of question in surveys, that allows to join a file as answer. This module provides a new type of question in surveys, that allows to join a file as answer.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com/',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'templates/upload_file.xml',
'templates/page.xml',
'templates/survey_print.xml',
'views/survey_user_input_line.xml',
"data": [
"templates/upload_file.xml",
"templates/page.xml",
"templates/survey_print.xml",
"views/survey_user_input_line.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': ['static/description/survey.jpg'],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

24
survey_input_attachment/i18n/fr.po

@ -21,15 +21,15 @@ msgid "Answer Type"
msgstr "Type de réponse" msgstr "Type de réponse"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:9
#: code:addons/survey_input_attachment/models/survey_question.py:10
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
msgid "Attachment"
msgstr "Pièce jointe"
msgid "Attachment (img/pdf)"
msgstr "Pièce jointe (img/pdf)"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:8
#: code:addons/survey_input_attachment/models/survey_question.py:9
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -47,7 +47,7 @@ msgid "File type"
msgstr "Type de fichier" msgstr "Type de fichier"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_user_input_line.py:7
#: code:addons/survey_input_attachment/models/survey_user_input_line.py:8
#: selection:survey.user_input_line,file_type:0 #: selection:survey.user_input_line,file_type:0
#, python-format #, python-format
msgid "Image" msgid "Image"
@ -59,7 +59,7 @@ msgid "Joined attachment"
msgstr "Pièce jointe" msgstr "Pièce jointe"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:12
#: code:addons/survey_input_attachment/models/survey_question.py:13
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -67,7 +67,7 @@ msgid "Matrix"
msgstr "Matrice" msgstr "Matrice"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:5
#: code:addons/survey_input_attachment/models/survey_question.py:6
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -75,7 +75,7 @@ msgid "Multiple Lines Text Box"
msgstr "Plusieurs lignes de champ de texte" msgstr "Plusieurs lignes de champ de texte"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:11
#: code:addons/survey_input_attachment/models/survey_question.py:12
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -83,7 +83,7 @@ msgid "Multiple choice: multiple answers allowed"
msgstr "Choix multiples : réponses multiples" msgstr "Choix multiples : réponses multiples"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:10
#: code:addons/survey_input_attachment/models/survey_question.py:11
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -91,7 +91,7 @@ msgid "Multiple choice: only one answer"
msgstr "Choix multiples : une seule réponse possible" msgstr "Choix multiples : une seule réponse possible"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:7
#: code:addons/survey_input_attachment/models/survey_question.py:8
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format
@ -99,14 +99,14 @@ msgid "Numerical Value"
msgstr "Valeur numérique" msgstr "Valeur numérique"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_user_input_line.py:8
#: code:addons/survey_input_attachment/models/survey_user_input_line.py:9
#: selection:survey.user_input_line,file_type:0 #: selection:survey.user_input_line,file_type:0
#, python-format #, python-format
msgid "PDF file" msgid "PDF file"
msgstr "Fichier PDF" msgstr "Fichier PDF"
#. module: survey_input_attachment #. module: survey_input_attachment
#: code:addons/survey_input_attachment/models/survey_question.py:6
#: code:addons/survey_input_attachment/models/survey_question.py:7
#: selection:survey.question,type:0 #: selection:survey.question,type:0
#: selection:survey.user_input_line,answer_type:0 #: selection:survey.user_input_line,answer_type:0
#, python-format #, python-format

28
survey_input_attachment/models/survey_question.py

@ -3,19 +3,19 @@ from odoo import models, fields, api, _
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
TYPES = [ TYPES = [
('free_text', _('Multiple Lines Text Box')),
('textbox', _('Single Line Text Box')),
('numerical_box', _('Numerical Value')),
('date', _('Date')),
('upload_file', _('Attachment')),
('simple_choice', _('Multiple choice: only one answer')),
('multiple_choice', _('Multiple choice: multiple answers allowed')),
('matrix', _('Matrix')),
("free_text", _("Multiple Lines Text Box")),
("textbox", _("Single Line Text Box")),
("numerical_box", _("Numerical Value")),
("date", _("Date")),
("upload_file", _("Attachment (img/pdf)")),
("simple_choice", _("Multiple choice: only one answer")),
("multiple_choice", _("Multiple choice: multiple answers allowed")),
("matrix", _("Matrix")),
] ]
class SurveyQuestion(models.Model): class SurveyQuestion(models.Model):
_inherit = 'survey.question'
_inherit = "survey.question"
# question_attachment = fields.Binary(string="Joined attachment") # question_attachment = fields.Binary(string="Joined attachment")
type = fields.Selection(selection=TYPES) type = fields.Selection(selection=TYPES)
@ -28,6 +28,12 @@ class SurveyQuestion(models.Model):
if self.constr_mandatory and not isinstance(post[answer_tag], FileStorage): if self.constr_mandatory and not isinstance(post[answer_tag], FileStorage):
errors.update({answer_tag: self.constr_error_msg}) errors.update({answer_tag: self.constr_error_msg})
# Bad file type # Bad file type
if isinstance(post[answer_tag], FileStorage) and post[answer_tag].content_type != 'application/pdf' and 'image/' not in post[answer_tag].content_type:
errors.update({answer_tag: _("The file you joined is not an image nor a PDF file.")})
if (
isinstance(post[answer_tag], FileStorage)
and post[answer_tag].content_type != "application/pdf"
and "image/" not in post[answer_tag].content_type
):
errors.update(
{answer_tag: _("The file you joined is not an image nor a PDF file.")}
)
return errors return errors

82
survey_input_attachment/models/survey_user_input_line.py

@ -3,64 +3,74 @@ import base64
from odoo import models, fields, api, _ from odoo import models, fields, api, _
ANSWER_TYPES = [ ANSWER_TYPES = [
('text', _('Text')),
('number', _('Number')),
('date', _('Date')),
('free_text', _('Free Text')),
('upload_file', _('Attachment')),
('suggestion', _('Suggestion')),
("text", _("Text")),
("number", _("Number")),
("date", _("Date")),
("free_text", _("Free Text")),
("upload_file", _("Attachment (img/pdf)")),
("suggestion", _("Suggestion")),
] ]
FILE_TYPES = [ FILE_TYPES = [
('image', _('Image')),
('pdf', _('PDF file')),
("image", _("Image")),
("pdf", _("PDF file")),
] ]
class SurveyUserInputLine(models.Model): class SurveyUserInputLine(models.Model):
_inherit = 'survey.user_input_line'
_inherit = "survey.user_input_line"
answer_type = fields.Selection(selection=ANSWER_TYPES) answer_type = fields.Selection(selection=ANSWER_TYPES)
file = fields.Binary(string='Uploaded file')
filename = fields.Char(string='Uploaded file name')
file = fields.Binary(string="Uploaded file")
filename = fields.Char(string="Uploaded file name")
file_type = fields.Selection(selection=FILE_TYPES, string="File type") file_type = fields.Selection(selection=FILE_TYPES, string="File type")
@api.model @api.model
def save_line_upload_file(self, user_input_id, question, post, answer_tag): def save_line_upload_file(self, user_input_id, question, post, answer_tag):
vals = { vals = {
'user_input_id': user_input_id,
'question_id': question.id,
'survey_id': question.survey_id.id,
'skipped': False
"user_input_id": user_input_id,
"question_id": question.id,
"survey_id": question.survey_id.id,
"skipped": False,
} }
file = False file = False
# import ipdb; ipdb.set_trace() # import ipdb; ipdb.set_trace()
if question.constr_mandatory: if question.constr_mandatory:
file = base64.encodebytes(post[answer_tag].read()) file = base64.encodebytes(post[answer_tag].read())
else: else:
file = base64.encodebytes(post[answer_tag].read()) if not isinstance(post[answer_tag], str) else None
file = (
base64.encodebytes(post[answer_tag].read())
if not isinstance(post[answer_tag], str)
else None
)
if answer_tag in post and not isinstance(post[answer_tag], str): if answer_tag in post and not isinstance(post[answer_tag], str):
vals.update({
'answer_type': 'upload_file',
'file': file,
'filename': post[answer_tag].filename,
})
if post[answer_tag].content_type == 'application/pdf':
vals.update({'file_type': 'pdf'})
if 'image/' in post[answer_tag].content_type:
vals.update({'file_type': 'image'})
vals.update(
{
"answer_type": "upload_file",
"file": file,
"filename": post[answer_tag].filename,
}
)
if post[answer_tag].content_type == "application/pdf":
vals.update({"file_type": "pdf"})
if "image/" in post[answer_tag].content_type:
vals.update({"file_type": "image"})
else: else:
vals.update({
'answer_type': None,
'file': False,
'filename': False,
'skipped': True,
})
old_uil = self.search([
('user_input_id', '=', user_input_id),
('survey_id', '=', question.survey_id.id),
('question_id', '=', question.id)
])
vals.update(
{
"answer_type": None,
"file": False,
"filename": False,
"skipped": True,
}
)
old_uil = self.search(
[
("user_input_id", "=", user_input_id),
("survey_id", "=", question.survey_id.id),
("question_id", "=", question.id),
]
)
if old_uil: if old_uil:
old_uil.write(vals) old_uil.write(vals)
else: else:

55
survey_input_dates/__manifest__.py

@ -1,32 +1,37 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey input dates',
'version': '1.0.0',
'summary': """
"name": "Survey input dates",
"version": "1.0.0",
"summary": """
This module adds date start and date done on surveys answers. This module adds date start and date done on surveys answers.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_user_input.xml',
"data": [
"views/survey_user_input.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

12
survey_input_dates/i18n/fr.po

@ -21,6 +21,18 @@ msgstr ""
msgid "Date done" msgid "Date done"
msgstr "Réponse terminée le" msgstr "Réponse terminée le"
#. module: survey_input_dates
#: code:addons/survey_input_dates/models/survey_user_input.py:27
#, python-format
msgid "Not done"
msgstr "Non terminé"
#. module: survey_input_dates
#: code:addons/survey_input_dates/models/survey_user_input.py:25
#, python-format
msgid "Not started"
msgstr "Non commencé"
#. module: survey_input_dates #. module: survey_input_dates
#: model:ir.model.fields,field_description:survey_input_dates.field_survey_user_input__date_start #: model:ir.model.fields,field_description:survey_input_dates.field_survey_user_input__date_start
msgid "Start date" msgid "Start date"

42
survey_input_dates/models/survey_user_input.py

@ -1,16 +1,42 @@
from odoo import models, fields, api
from odoo import models, fields, api, _
class SurveyUserInput(models.Model): class SurveyUserInput(models.Model):
_inherit = 'survey.user_input'
_inherit = "survey.user_input"
date_start = fields.Datetime(string="Start date", readonly=True, help="This date is set when the user clicks on \"Start survey\" button for the first time.")
date_done = fields.Datetime(string="Date done", readonly=True, help="This date is set when the user input is set ton \"Done\" status.")
date_start = fields.Datetime(
string="Start date",
readonly=True,
help='This date is set when the user clicks on "Start survey" button for the first time.',
)
date_done = fields.Datetime(
string="Date done",
readonly=True,
help='This date is set when the user input is set ton "Done" status.',
)
duration = fields.Integer(
string="Duration",
compute="_get_duration",
store=True,
help="Time expressed in seconds, neet 'duration' widget to be read by user.",
)
@api.depends("date_start", "date_stop")
def _get_duration(self):
for input in self:
start = input.date_start
done = input.date_done
if not start and done:
input.duration = 0
else:
input.duration = int((done - start).total_seconds())
@api.multi @api.multi
def write(self, vals): def write(self, vals):
if vals.get('state', False) == 'done':
vals.update({
'date_done': fields.Datetime.now(),
})
if vals.get("state", False) == "done":
vals.update(
{
"date_done": fields.Datetime.now(),
}
)
return super(SurveyUserInput, self).write(vals) return super(SurveyUserInput, self).write(vals)

3
survey_input_dates/views/survey_user_input.xml

@ -11,6 +11,7 @@
<field name="date_create" position="after"> <field name="date_create" position="after">
<field name="date_start"/> <field name="date_start"/>
<field name="date_done"/> <field name="date_done"/>
<field name="duration" widget="duration" options="{'unit': 'second', 'round': 'second'}"/>
</field> </field>
</field> </field>
</record> </record>
@ -25,6 +26,7 @@
<field name="date_create" position="after"> <field name="date_create" position="after">
<field name="date_start"/> <field name="date_start"/>
<field name="date_done"/> <field name="date_done"/>
<field name="duration" widget="duration" options="{'unit': 'minute', 'round': 'minute'}"/>
</field> </field>
</field> </field>
</record> </record>
@ -39,6 +41,7 @@
<field name="date_create" position="after"> <field name="date_create" position="after">
<field name="date_start"/> <field name="date_start"/>
<field name="date_done"/> <field name="date_done"/>
<!-- <field name="duration"/> -->
</field> </field>
</field> </field>
</record> </record>

55
survey_input_odoo_debrand/__manifest__.py

@ -1,32 +1,37 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey input debranding',
'version': '1.0.0',
'summary': """
"name": "Survey input debranding",
"version": "1.0.0",
"summary": """
This module removes the \"Create a free website with odoo\" mention at the bottom right of survey inputs. This module removes the \"Create a free website with odoo\" mention at the bottom right of survey inputs.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'templates/layout.xml',
"data": [
"templates/layout.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

63
survey_input_template_custom/__manifest__.py

@ -1,36 +1,41 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey input custom',
'version': '1.0.0',
'summary': """
"name": "Survey input custom",
"version": "1.0.0",
"summary": """
This module allows to customize the survey start button label and the \"Thank you\" page title. This module allows to customize the survey start button label and the \"Thank you\" page title.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey_description',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey_description",
], ],
'data': [
'templates/layout.xml',
'templates/page.xml',
'templates/sfinished.xml',
'templates/survey_init.xml',
'views/survey_survey.xml',
"data": [
"templates/layout.xml",
"templates/page.xml",
"templates/sfinished.xml",
"templates/survey_init.xml",
"views/survey_survey.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

55
survey_link_input_ratio/__manifest__.py

@ -1,32 +1,37 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey sent answer ratio',
'version': '1.0.0',
'summary': """
"name": "Survey sent answer ratio",
"version": "1.0.0",
"summary": """
This module displays percent pies statistics on sent inputs in survey form stat-buttons. This module displays percent pies statistics on sent inputs in survey form stat-buttons.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_survey.xml',
"data": [
"views/survey_survey.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

88
survey_link_input_ratio/models/survey_survey.py

@ -3,62 +3,100 @@ from odoo.osv.expression import normalize_domain, AND
class SurveySurvey(models.Model): class SurveySurvey(models.Model):
_inherit = 'survey.survey'
_inherit = "survey.survey"
tot_sent_start_survey = fields.Integer("Started sent survey count", compute="_count_sent_input")
tot_sent_comp_survey = fields.Integer("Completed sent survey count", compute="_count_sent_input")
sent_start_ratio = fields.Integer(string="Started sent survey ratio", compute="_get_sent_start_ratio")
sent_comp_ratio = fields.Integer(string="Completed sent survey ratio", compute="_get_sent_comp_ratio")
tot_sent_start_survey = fields.Integer(
"Started sent survey count", compute="_count_sent_input"
)
tot_sent_comp_survey = fields.Integer(
"Completed sent survey count", compute="_count_sent_input"
)
sent_start_ratio = fields.Integer(
string="Started sent survey ratio", compute="_get_sent_start_ratio"
)
sent_comp_ratio = fields.Integer(
string="Completed sent survey ratio", compute="_get_sent_comp_ratio"
)
# COMPUTES # COMPUTES
@api.multi @api.multi
def _count_sent_input(self): def _count_sent_input(self):
UserInput = self.env['survey.user_input']
sent_start_survey = UserInput.search([('survey_id', 'in', self.ids), ('type', '=', 'link'), ('state', '=', 'skip')])
sent_comp_survey = UserInput.search([('survey_id', 'in', self.ids), ('type', '=', 'link'), ('state', '=', 'done')])
UserInput = self.env["survey.user_input"]
sent_start_survey = UserInput.search(
[
("survey_id", "in", self.ids),
("type", "=", "link"),
("state", "=", "skip"),
]
)
sent_comp_survey = UserInput.search(
[
("survey_id", "in", self.ids),
("type", "=", "link"),
("state", "=", "done"),
]
)
for survey in self: for survey in self:
survey.tot_sent_start_survey = len(sent_start_survey.filtered(lambda user_input: user_input.survey_id == survey))
survey.tot_sent_comp_survey = len(sent_comp_survey.filtered(lambda user_input: user_input.survey_id == survey))
survey.tot_sent_start_survey = len(
sent_start_survey.filtered(
lambda user_input: user_input.survey_id == survey
)
)
survey.tot_sent_comp_survey = len(
sent_comp_survey.filtered(
lambda user_input: user_input.survey_id == survey
)
)
@api.depends('tot_sent_start_survey', 'tot_sent_survey')
@api.depends("tot_sent_start_survey", "tot_sent_survey")
def _get_sent_start_ratio(self): def _get_sent_start_ratio(self):
for survey in self: for survey in self:
if survey.tot_sent_survey == 0: if survey.tot_sent_survey == 0:
survey.sent_start_ratio = 0 survey.sent_start_ratio = 0
else: else:
survey.sent_start_ratio = int(round(100 * (survey.tot_sent_start_survey) / survey.tot_sent_survey, 0))
survey.sent_start_ratio = int(
round(
100 * (survey.tot_sent_start_survey) / survey.tot_sent_survey, 0
)
)
@api.depends('tot_sent_comp_survey', 'tot_sent_survey')
@api.depends("tot_sent_comp_survey", "tot_sent_survey")
def _get_sent_comp_ratio(self): def _get_sent_comp_ratio(self):
for survey in self: for survey in self:
if survey.tot_sent_survey == 0: if survey.tot_sent_survey == 0:
survey.sent_comp_ratio = 0 survey.sent_comp_ratio = 0
else: else:
survey.sent_comp_ratio = int(round(100 * survey.tot_sent_comp_survey / survey.tot_sent_survey, 0))
survey.sent_comp_ratio = int(
round(100 * survey.tot_sent_comp_survey / survey.tot_sent_survey, 0)
)
# ACTIONS # ACTIONS
@api.multi @api.multi
def action_survey_user_input(self): def action_survey_user_input(self):
ctx = dict(self.env.context) ctx = dict(self.env.context)
search_completed = ctx.get('search_default_completed', None)
search_completed = ctx.get("search_default_completed", None)
action = super(SurveySurvey, self).action_survey_user_input() action = super(SurveySurvey, self).action_survey_user_input()
if ctx.get('link_only', False):
domain = action.get('domain') or []
if ctx.get("link_only", False):
domain = action.get("domain") or []
if isinstance(domain, str): if isinstance(domain, str):
domain = eval(domain) domain = eval(domain)
if len(domain) > 1: if len(domain) > 1:
action['domain'] = AND([[('type', '=', 'link')], normalize_domain(domain)])
action["domain"] = AND(
[[("type", "=", "link")], normalize_domain(domain)]
)
else: else:
action['domain'] = [('type', '=', 'link')]
action['display_name'] += _(" (from private links)")
action["domain"] = [("type", "=", "link")]
action["display_name"] += _(" (from private links)")
if search_completed is not None: if search_completed is not None:
act_ctx = action.get('context') or {}
act_ctx = action.get("context") or {}
if isinstance(act_ctx, str): if isinstance(act_ctx, str):
act_ctx = eval(act_ctx) act_ctx = eval(act_ctx)
if 'search_default_completed' in act_ctx:
if bool(act_ctx['search_default_completed']) is not bool(search_completed):
act_ctx['search_default_completed'] = int(bool(search_completed))
action['context'] = act_ctx
if "search_default_completed" in act_ctx:
if bool(act_ctx["search_default_completed"]) is not bool(
search_completed
):
act_ctx["search_default_completed"] = int(bool(search_completed))
action["context"] = act_ctx
return action return action

24
survey_link_input_ratio/views/survey_survey.xml

@ -27,28 +27,4 @@
</field> </field>
</record> </record>
<!-- <record id="survey_survey_tree" model="ir.ui.view">
<field name="name">OT31 SURVEY survey.survey tree</field>
<field name="model">survey.survey</field>
<field name="inherit_id" ref="survey.survey_tree"/>
<field name="priority">36</field>
<field name="arch" type="xml">
<field name="title" position="after">
<field name="aa_type"/>
</field>
</field>
</record> -->
<!-- <record id="survey_survey_kanban" model="ir.ui.view">
<field name="name">OT31 SURVEY survey.survey kanban</field>
<field name="model">survey.survey</field>
<field name="inherit_id" ref="survey.survey_kanban"/>
<field name="priority">36</field>
<field name="arch" type="xml">
<field name="title" position="after">
<field name="aa_type" readonly="1"/>
</field>
</field>
</record> -->
</odoo> </odoo>

57
survey_partner_input/__manifest__.py

@ -1,33 +1,38 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey partner answers',
'version': '1.0.0',
'summary': """
"name": "Survey partner answers",
"version": "1.0.0",
"summary": """
This module displays a counter and a percent pie on partner survey answers statistics in form stat-buttons. This module displays a counter and a percent pie on partner survey answers statistics in form stat-buttons.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/res_partner.xml',
'views/survey_user_input.xml',
"data": [
"views/res_partner.xml",
"views/survey_user_input.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

92
survey_partner_input/models/res_partner.py

@ -3,83 +3,115 @@ from odoo.osv.expression import normalize_domain, AND
class ResPartner(models.Model): class ResPartner(models.Model):
_inherit = 'res.partner'
_inherit = "res.partner"
tot_sent_survey = fields.Integer("Sent survey count", compute="_count_survey_input") tot_sent_survey = fields.Integer("Sent survey count", compute="_count_survey_input")
tot_comp_survey = fields.Integer("Completed survey count", compute="_count_survey_input")
tot_sent_comp_survey = fields.Integer("Completed sent survey count", compute="_count_survey_input")
sent_comp_ratio = fields.Integer(string="Completed sent survey ratio", compute="_get_sent_comp_ratio")
tot_comp_survey = fields.Integer(
"Completed survey count", compute="_count_survey_input"
)
tot_sent_comp_survey = fields.Integer(
"Completed sent survey count", compute="_count_survey_input"
)
sent_comp_ratio = fields.Integer(
string="Completed sent survey ratio", compute="_get_sent_comp_ratio"
)
# COMPUTES # COMPUTES
@api.multi @api.multi
def _count_survey_input(self): def _count_survey_input(self):
UserInput = self.env['survey.user_input']
UserInput = self.env["survey.user_input"]
partners_survey = UserInput partners_survey = UserInput
in_onchange = self.env.in_onchange in_onchange = self.env.in_onchange
origin = in_onchange and self._origin or False origin = in_onchange and self._origin or False
if in_onchange: if in_onchange:
domain = [ domain = [
('partner_id', '=', self._origin.id),
'|', ('type', '=', 'link'),
('state', '=', 'dones'),
("partner_id", "=", self._origin.id),
"|",
("type", "=", "link"),
("state", "=", "dones"),
] ]
if self.email: if self.email:
domain = ['|', ('email', '=', self.email)] + domain
domain = ["|", ("email", "=", self.email)] + domain
partners_survey = UserInput.search(domain) partners_survey = UserInput.search(domain)
else: else:
partners_survey = UserInput.search([
'|', ('partner_id', 'in', self.ids),
('email', 'in', self.filtered('email').mapped('email')),
'|', ('type', '=', 'link'),
('state', '=', 'done'),
])
partners_survey = UserInput.search(
[
"|",
("partner_id", "in", self.ids),
("email", "in", self.filtered("email").mapped("email")),
"|",
("type", "=", "link"),
("state", "=", "done"),
]
)
for partner in self: for partner in self:
done = partners_survey.filtered(lambda sui: (sui.partner_id == (origin or partner) or partner.email and sui.email == partner.email) and sui.state == 'done')
link = partners_survey.filtered(lambda sui: (sui.partner_id == (origin or partner) or partner.email and sui.email == partner.email) and sui.type == 'link')
done = partners_survey.filtered(
lambda sui: (
sui.partner_id == (origin or partner)
or partner.email
and sui.email == partner.email
)
and sui.state == "done"
)
link = partners_survey.filtered(
lambda sui: (
sui.partner_id == (origin or partner)
or partner.email
and sui.email == partner.email
)
and sui.type == "link"
)
partner.tot_sent_survey = len(link) partner.tot_sent_survey = len(link)
partner.tot_comp_survey = len(done) partner.tot_comp_survey = len(done)
partner.tot_sent_comp_survey = len(link & done) partner.tot_sent_comp_survey = len(link & done)
@api.depends('tot_sent_comp_survey', 'tot_sent_survey')
@api.depends("tot_sent_comp_survey", "tot_sent_survey")
def _get_sent_comp_ratio(self): def _get_sent_comp_ratio(self):
for survey in self: for survey in self:
if survey.tot_sent_survey == 0: if survey.tot_sent_survey == 0:
survey.sent_comp_ratio = 0 survey.sent_comp_ratio = 0
else: else:
survey.sent_comp_ratio = int(round(100 * survey.tot_sent_comp_survey / survey.tot_sent_survey, 0))
survey.sent_comp_ratio = int(
round(100 * survey.tot_sent_comp_survey / survey.tot_sent_survey, 0)
)
# ACTIONS # ACTIONS
@api.multi @api.multi
def action_survey_user_input(self): def action_survey_user_input(self):
self.ensure_one() self.ensure_one()
action = self.env.ref('survey.action_survey_user_input').read()[0]
action['display_name'] += _(" from {}").format(self.display_name)
action = self.env.ref("survey.action_survey_user_input").read()[0]
action["display_name"] += _(" from {}").format(self.display_name)
# manage context # manage context
ctx = dict(self.env.context) ctx = dict(self.env.context)
link_only = ctx.pop('link_only', False)
action['context'] = ctx
link_only = ctx.pop("link_only", False)
action["context"] = ctx
# manage domain # manage domain
domain = action.get('domain') or []
domain = action.get("domain") or []
if isinstance(domain, str): if isinstance(domain, str):
domain = eval(domain) domain = eval(domain)
if len(domain) > 1: if len(domain) > 1:
domain = AND([['|', ('partner_id', '=', self.id), ('email', 'ilike', self.email)], normalize_domain(domain)])
domain = AND(
[
["|", ("partner_id", "=", self.id), ("email", "ilike", self.email)],
normalize_domain(domain),
]
)
else: else:
domain = ['|', ('partner_id', '=', self.id), ('email', 'ilike', self.email)]
domain = ["|", ("partner_id", "=", self.id), ("email", "ilike", self.email)]
if link_only: if link_only:
if len(domain) > 1: if len(domain) > 1:
domain = AND([[('type', '=', 'link')], normalize_domain(domain)])
domain = AND([[("type", "=", "link")], normalize_domain(domain)])
else: else:
domain = [('type', '=', 'link')]
action['domain'] = domain
domain = [("type", "=", "link")]
action["domain"] = domain
# return updated action # return updated action
return action return action
# ONCHANGES # ONCHANGES
@api.onchange('email')
@api.onchange("email")
def onchange_email(self): def onchange_email(self):
self.ensure_one() self.ensure_one()
if isinstance(self._origin.id, int): if isinstance(self._origin.id, int):

55
survey_question_duplicate/__manifest__.py

@ -1,32 +1,37 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey question duplicate',
'version': '1.0.0',
'summary': """
"name": "Survey question duplicate",
"version": "1.0.0",
"summary": """
This module adds a \"Copy\" button in question lines on survey page form, only in edit mode. This module adds a \"Copy\" button in question lines on survey page form, only in edit mode.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com/',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_page.xml',
"data": [
"views/survey_page.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': ['static/description/survey.jpg'],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

57
survey_select_input/__manifest__.py

@ -1,33 +1,38 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey answer selection',
'version': '1.0.0',
'summary': """
"name": "Survey answer selection",
"version": "1.0.0",
"summary": """
This module adds the mossibility to select some of the surveys answers. This module adds the mossibility to select some of the surveys answers.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_survey.xml',
'views/survey_user_input.xml',
"data": [
"views/survey_survey.xml",
"views/survey_user_input.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

55
survey_template/__manifest__.py

@ -1,32 +1,37 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{ {
'name': 'Survey template',
'version': '1.0.0',
'summary': """
"name": "Survey template",
"version": "1.0.0",
"summary": """
This module adds templating feature on surveys and their own menu item. This module adds templating feature on surveys and their own menu item.
""", """,
'description': """ """,
'author': 'Sudokeys',
'website': 'http://www.sudokeys.com',
'license': 'AGPL-3',
'category': 'Marketing',
'depends': [
'survey',
"description": """ """,
"author": "RemiFr82",
"contributors": "",
"website": "https://remifr82.me",
"license": "LGPL-3",
"category": "Marketing",
# "price": 0,
# "currency": "EUR",
"application": False,
"installable": True,
"auto_install": False,
"pre_init_hook": "",
"post_init_hook": "",
"uninstall_hook": "",
"excludes": [],
"external_dependencies": [],
"depends": [
"survey",
], ],
'data': [
'views/survey_survey.xml',
"data": [
"views/survey_survey.xml",
], ],
'demo': [],
'auto_install': False,
'external_dependencies': [],
'application': False,
'css': [],
'images': [],
'js': [],
'installable': True,
'maintainer': 'Sudokeys',
'pre_init_hook': '',
'post_init_hook': '',
'uninstall_hook': '',
"css": [],
"images": [],
"js": [],
"test": [],
"demo": [],
"maintainer": "RemiFr82",
} }

56
survey_template/models/survey_survey.py

@ -3,18 +3,18 @@ from odoo.exceptions import UserError
class SurveySurvey(models.Model): class SurveySurvey(models.Model):
_inherit = 'survey.survey'
_inherit = "survey.survey"
is_template = fields.Boolean(string="Is a template", default=False, copy=False) is_template = fields.Boolean(string="Is a template", default=False, copy=False)
@api.multi @api.multi
def copy_data(self, default=None): def copy_data(self, default=None):
data = super(SurveySurvey, self).copy_data(default)[0] data = super(SurveySurvey, self).copy_data(default)[0]
title = isinstance(default, dict) and default.get('title', False) or False
title = isinstance(default, dict) and default.get("title", False) or False
if title: if title:
data['title'] = title
elif _(" (Template)") in data['title']:
data['title'] = data['title'].replace(_(" (Template)"), "")
data["title"] = title
elif _(" (Template)") in data["title"]:
data["title"] = data["title"].replace(_(" (Template)"), "")
return [data] return [data]
# ACTIONS # ACTIONS
@ -23,43 +23,55 @@ class SurveySurvey(models.Model):
def create_template_from_survey(self, default={}): def create_template_from_survey(self, default={}):
self.ensure_one() self.ensure_one()
if self.is_template: if self.is_template:
raise UserError(_("You should use the \"Copy\" secondary action to duplicate a survey template."))
default.update({'is_template': True})
raise UserError(
_(
'You should use the "Copy" secondary action to duplicate a survey template.'
)
)
default.update({"is_template": True})
new_survey = self.copy(default=default) new_survey = self.copy(default=default)
return { return {
'type': 'ir.actions.act_window',
'res_model': 'survey.survey',
'view_type': 'form',
'view_mode': 'form',
'target': 'current',
'res_id': new_survey.id,
"type": "ir.actions.act_window",
"res_model": "survey.survey",
"view_type": "form",
"view_mode": "form",
"target": "current",
"res_id": new_survey.id,
} }
@api.multi @api.multi
def create_survey_from_template(self, default={}): def create_survey_from_template(self, default={}):
self.ensure_one() self.ensure_one()
if not self.is_template: if not self.is_template:
raise UserError(_("You should use the \"Copy\" secondary action to duplicate a non-template survey."))
raise UserError(
_(
'You should use the "Copy" secondary action to duplicate a non-template survey.'
)
)
new_survey = self.copy(default=default) new_survey = self.copy(default=default)
return { return {
'type': 'ir.actions.act_window',
'res_model': 'survey.survey',
'view_type': 'form',
'view_mode': 'form',
'target': 'current',
'res_id': new_survey.id,
"type": "ir.actions.act_window",
"res_model": "survey.survey",
"view_type": "form",
"view_mode": "form",
"target": "current",
"res_id": new_survey.id,
} }
@api.multi @api.multi
def action_send_survey(self): def action_send_survey(self):
self.ensure_one() self.ensure_one()
if self.is_template: if self.is_template:
raise UserError(_("You cannot send a template survey, create a new survey from this template and you'll be able to share it."))
raise UserError(
_(
"You cannot send a template survey, create a new survey from this template and you'll be able to share it."
)
)
return super(SurveySurvey, self).action_send_survey() return super(SurveySurvey, self).action_send_survey()
# ONCHANGES # ONCHANGES
@api.onchange('is_template')
@api.onchange("is_template")
def onchange_is_template(self): def onchange_is_template(self):
if self.title: if self.title:
if self.is_template: if self.is_template:

Loading…
Cancel
Save