[MERGE][REF] various: rename columns "type" to be more business oriented

Purpose of this commit is to rename type column to something matching the
the real business use of the field. That way it is easier to find and grep
in the code. It also lessens potential conflicts with type build-in python
function. It also lessens conflicts when using the field in JS as type
is a build-in attribute.

Renaming type column is a long-living issue. We choose to do it at the
beginning of the v13 development to catch errors as soon as possible.

This commit is linked to task ID 1896245. It is also a subpart of community
PR #27599.

closes odoo/odoo#27722
This commit is contained in:
Robot Odoo
2018-10-19 14:16:32 +02:00
committed by GitHub
25 changed files with 197 additions and 197 deletions
+7 -7
View File
@@ -11,43 +11,43 @@
<field name="name">15 Minute(s)</field>
<field name="duration" eval="15" />
<field name="interval">minutes</field>
<field name="type">notification</field>
<field name="alarm_type">notification</field>
</record>
<record id="alarm_notif_2" model="calendar.alarm">
<field name="name">30 Minute(s)</field>
<field name="duration" eval="30" />
<field name="interval">minutes</field>
<field name="type">notification</field>
<field name="alarm_type">notification</field>
</record>
<record id="alarm_notif_3" model="calendar.alarm">
<field name="name">1 Hour(s)</field>
<field name="duration" eval="1" />
<field name="interval">hours</field>
<field name="type">notification</field>
<field name="alarm_type">notification</field>
</record>
<record id="alarm_notif_4" model="calendar.alarm">
<field name="name">2 Hour(s)</field>
<field name="duration" eval="2" />
<field name="interval">hours</field>
<field name="type">notification</field>
<field name="alarm_type">notification</field>
</record>
<record id="alarm_notif_5" model="calendar.alarm">
<field name="name">1 Day(s)</field>
<field name="duration" eval="1" />
<field name="interval">days</field>
<field name="type">notification</field>
<field name="alarm_type">notification</field>
</record>
<record id="alarm_mail_1" model="calendar.alarm">
<field name="name">3 Hour(s), by e-mail</field>
<field name="duration" eval="3" />
<field name="interval">hours</field>
<field name="type">email</field>
<field name="alarm_type">email</field>
</record>
<record id="alarm_mail_2" model="calendar.alarm">
<field name="name">6 Hour(s), by e-mail</field>
<field name="duration" eval="6" />
<field name="interval">hours</field>
<field name="type">email</field>
<field name="alarm_type">email</field>
</record>
</data>
</odoo>
+6 -6
View File
@@ -251,7 +251,7 @@ class AlarmManager(models.AbstractModel):
FROM
calendar_alarm_calendar_event_rel AS rel
LEFT JOIN calendar_alarm AS alarm ON alarm.id = rel.calendar_alarm_id
WHERE alarm.type = %s
WHERE alarm.alarm_type = %s
GROUP BY rel.calendar_event_id
"""
base_request = """
@@ -340,7 +340,7 @@ class AlarmManager(models.AbstractModel):
# TODO: remove event_maxdelta and if using it
if one_date - timedelta(minutes=(missing and 0 or event_maxdelta)) < datetime.datetime.now() + timedelta(seconds=in_the_next_X_seconds): # if an alarm is possible for this date
for alarm in event.alarm_ids:
if alarm.type == alarm_type and \
if alarm.alarm_type == alarm_type and \
one_date - timedelta(minutes=(missing and 0 or alarm.duration_minutes)) < datetime.datetime.now() + timedelta(seconds=in_the_next_X_seconds) and \
(not after or one_date - timedelta(minutes=alarm.duration_minutes) > fields.Datetime.from_string(after)):
alert = {
@@ -438,7 +438,7 @@ class AlarmManager(models.AbstractModel):
alarm = self.env['calendar.alarm'].browse(alert['alarm_id'])
result = False
if alarm.type == 'email':
if alarm.alarm_type == 'email':
result = meeting.attendee_ids.filtered(lambda r: r.state != 'declined')._send_mail_to_attendees('calendar.calendar_template_meeting_reminder', force_send=True)
return result
@@ -446,7 +446,7 @@ class AlarmManager(models.AbstractModel):
alarm = self.env['calendar.alarm'].browse(alert['alarm_id'])
meeting = self.env['calendar.event'].browse(alert['event_id'])
if alarm.type == 'notification':
if alarm.alarm_type == 'notification':
message = meeting.display_time
delta = alert['notify_at'] - datetime.datetime.now()
@@ -490,7 +490,7 @@ class Alarm(models.Model):
_interval_selection = {'minutes': 'Minute(s)', 'hours': 'Hour(s)', 'days': 'Day(s)'}
name = fields.Char('Name', translate=True, required=True)
type = fields.Selection([('notification', 'Notification'), ('email', 'Email')], 'Type', required=True, default='email')
alarm_type = fields.Selection([('notification', 'Notification'), ('email', 'Email')], string='Type', required=True, default='email', oldname='type')
duration = fields.Integer('Remind Before', required=True, default=1)
interval = fields.Selection(list(_interval_selection.items()), 'Unit', required=True, default='hours')
duration_minutes = fields.Integer('Duration in minutes', compute='_compute_duration_minutes', store=True, help="Duration in minutes")
@@ -505,7 +505,7 @@ class Alarm(models.Model):
cron = self.env['ir.model.data'].sudo().get_object('calendar', 'ir_cron_scheduler_alarm')
except ValueError:
return False
return cron.toggle(model=self._name, domain=[('type', '=', 'email')])
return cron.toggle(model=self._name, domain=[('alarm_type', '=', 'email')])
@api.model
def create(self, values):
+1 -1
View File
@@ -93,7 +93,7 @@ class TestCalendar(TransactionCase):
'name': '1 Day before event starts',
'duration': 1,
'interval': 'days',
'type': 'notification'
'alarm_type': 'notification'
})
# Now I will assign this reminder to all day event|
+2 -2
View File
@@ -26,7 +26,7 @@
<field name="arch" type="xml">
<tree string="Calendar Alarm" editable="bottom">
<field name="name"/>
<field name="type"/>
<field name="alarm_type"/>
<field name="duration"/>
<field name="interval"/>
</tree>
@@ -41,7 +41,7 @@
<group>
<group>
<field name="name"/>
<field name="type" groups="base.group_no_one"/>
<field name="alarm_type" groups="base.group_no_one"/>
</group>
<group>
<label for="duration"/>
+1 -1
View File
@@ -28,7 +28,7 @@ class CalendarEvent(models.Model):
class CalendarAlarm(models.Model):
_inherit = 'calendar.alarm'
type = fields.Selection(selection_add=[('sms', 'SMS Text Message')])
alarm_type = fields.Selection(selection_add=[('sms', 'SMS Text Message')])
class AlarmManager(models.AbstractModel):
+1 -1
View File
@@ -174,7 +174,7 @@ class DeliveryCarrier(models.Model):
env = api.Environment(cr, SUPERUSER_ID, {})
IrLogging = env['ir.logging']
IrLogging.sudo().create({'name': 'delivery.carrier',
'type': 'server',
'logging_type': 'server',
'dbname': db_name,
'level': 'DEBUG',
'message': xml_string,
+22 -22
View File
@@ -33,11 +33,11 @@ class FetchmailServer(models.Model):
], string='Status', index=True, readonly=True, copy=False, default='draft')
server = fields.Char(string='Server Name', readonly=True, help="Hostname or IP of the mail server", states={'draft': [('readonly', False)]})
port = fields.Integer(readonly=True, states={'draft': [('readonly', False)]})
type = fields.Selection([
server_type = fields.Selection([
('pop', 'POP Server'),
('imap', 'IMAP Server'),
('local', 'Local Server'),
], 'Server Type', index=True, required=True, default='pop')
], string='Server Type', index=True, required=True, default='pop', oldname='type')
is_ssl = fields.Boolean('SSL/TLS', help="Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP3S=995)")
attach = fields.Boolean('Keep Attachments', help="Whether attachments should be downloaded. "
"If not enabled, incoming emails will be stripped of any attachments before being processed", default=True)
@@ -55,12 +55,12 @@ class FetchmailServer(models.Model):
configuration = fields.Text('Configuration', readonly=True)
script = fields.Char(readonly=True, default='/mail/static/scripts/openerp_mailgate.py')
@api.onchange('type', 'is_ssl', 'object_id')
@api.onchange('server_type', 'is_ssl', 'object_id')
def onchange_server_type(self):
self.port = 0
if self.type == 'pop':
if self.server_type == 'pop':
self.port = self.is_ssl and 995 or 110
elif self.type == 'imap':
elif self.server_type == 'imap':
self.port = self.is_ssl and 993 or 143
else:
self.server = ''
@@ -106,13 +106,13 @@ class FetchmailServer(models.Model):
@api.multi
def connect(self):
self.ensure_one()
if self.type == 'imap':
if self.server_type == 'imap':
if self.is_ssl:
connection = IMAP4_SSL(self.server, int(self.port))
else:
connection = IMAP4(self.server, int(self.port))
connection.login(self.user, self.password)
elif self.type == 'pop':
elif self.server_type == 'pop':
if self.is_ssl:
connection = POP3_SSL(self.server, int(self.port))
else:
@@ -132,14 +132,14 @@ class FetchmailServer(models.Model):
connection = server.connect()
server.write({'state': 'done'})
except Exception as err:
_logger.info("Failed to connect to %s server %s.", server.type, server.name, exc_info=True)
_logger.info("Failed to connect to %s server %s.", server.server_type, server.name, exc_info=True)
raise UserError(_("Connection test failed: %s") % tools.ustr(err))
finally:
try:
if connection:
if server.type == 'imap':
if server.server_type == 'imap':
connection.close()
elif server.type == 'pop':
elif server.server_type == 'pop':
connection.quit()
except Exception:
# ignored, just a consequence of the previous exception
@@ -149,7 +149,7 @@ class FetchmailServer(models.Model):
@api.model
def _fetch_mails(self):
""" Method called by cron to fetch mails from servers """
return self.search([('state', '=', 'done'), ('type', 'in', ['pop', 'imap'])]).fetch_mail()
return self.search([('state', '=', 'done'), ('server_type', 'in', ['pop', 'imap'])]).fetch_mail()
@api.multi
def fetch_mail(self):
@@ -159,13 +159,13 @@ class FetchmailServer(models.Model):
}
MailThread = self.env['mail.thread']
for server in self:
_logger.info('start checking for new emails on %s server %s', server.type, server.name)
_logger.info('start checking for new emails on %s server %s', server.server_type, server.name)
additionnal_context['fetchmail_server_id'] = server.id
additionnal_context['server_type'] = server.type
additionnal_context['server_type'] = server.server_type
count, failed = 0, 0
imap_server = None
pop_server = None
if server.type == 'imap':
if server.server_type == 'imap':
try:
imap_server = server.connect()
imap_server.select()
@@ -177,19 +177,19 @@ class FetchmailServer(models.Model):
try:
res_id = MailThread.with_context(**additionnal_context).message_process(server.object_id.model, data[0][1], save_original=server.original, strip_attachments=(not server.attach))
except Exception:
_logger.info('Failed to process mail from %s server %s.', server.type, server.name, exc_info=True)
_logger.info('Failed to process mail from %s server %s.', server.server_type, server.name, exc_info=True)
failed += 1
imap_server.store(num, '+FLAGS', '\\Seen')
self._cr.commit()
count += 1
_logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", count, server.type, server.name, (count - failed), failed)
_logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", count, server.server_type, server.name, (count - failed), failed)
except Exception:
_logger.info("General failure when trying to fetch mail from %s server %s.", server.type, server.name, exc_info=True)
_logger.info("General failure when trying to fetch mail from %s server %s.", server.server_type, server.name, exc_info=True)
finally:
if imap_server:
imap_server.close()
imap_server.logout()
elif server.type == 'pop':
elif server.server_type == 'pop':
try:
while True:
pop_server = server.connect()
@@ -203,15 +203,15 @@ class FetchmailServer(models.Model):
res_id = MailThread.with_context(**additionnal_context).message_process(server.object_id.model, message, save_original=server.original, strip_attachments=(not server.attach))
pop_server.dele(num)
except Exception:
_logger.info('Failed to process mail from %s server %s.', server.type, server.name, exc_info=True)
_logger.info('Failed to process mail from %s server %s.', server.server_type, server.name, exc_info=True)
failed += 1
self.env.cr.commit()
if num_messages < MAX_POP_MESSAGES:
break
pop_server.quit()
_logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", num_messages, server.type, server.name, (num_messages - failed), failed)
_logger.info("Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", num_messages, server.server_type, server.name, (num_messages - failed), failed)
except Exception:
_logger.info("General failure when trying to fetch mail from %s server %s.", server.type, server.name, exc_info=True)
_logger.info("General failure when trying to fetch mail from %s server %s.", server.server_type, server.name, exc_info=True)
finally:
if pop_server:
pop_server.quit()
@@ -225,6 +225,6 @@ class FetchmailServer(models.Model):
try:
# Enabled/Disable cron based on the number of 'done' server of type pop or imap
cron = self.env.ref('fetchmail.ir_cron_mail_gateway_action')
cron.toggle(model=self._name, domain=[('state', '=', 'done'), ('type', 'in', ['pop', 'imap'])])
cron.toggle(model=self._name, domain=[('state', '=', 'done'), ('server_type', 'in', ['pop', 'imap'])])
except ValueError:
pass
+12 -12
View File
@@ -7,7 +7,7 @@
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'" string="POP/IMAP Servers">
<field name="name"/>
<field name="type"/>
<field name="server_type"/>
<field name="is_ssl"/>
<field name="object_id"/>
<field name="date"/>
@@ -22,7 +22,7 @@
<field name="model">fetchmail.server</field>
<field name="arch" type="xml">
<form string="Incoming Mail Server">
<header attrs="{'invisible' : [('type', '=', 'local')]}">
<header attrs="{'invisible' : [('server_type', '=', 'local')]}">
<button string="Test &amp; Confirm" type="object" name="button_confirm_login" states="draft"/>
<button string="Fetch Now" type="object" name="fetch_mail" states="done"/>
<button string="Reset Confirmation" type="object" name="set_draft" states="done"/>
@@ -31,25 +31,25 @@
<sheet>
<group col="4">
<field name="name"/>
<field name="type"/>
<field name="server_type"/>
<field name="date"/>
</group>
<notebook>
<page string="Server &amp; Login">
<group>
<group attrs="{'invisible' : [('type', '=', 'local')]}" string="Server Information">
<field name="server" colspan="2" attrs="{'required' : [('type', '!=', 'local')]}" />
<field name="port" required="1" attrs="{'required' : [('type', '!=', 'local')]}" />
<group attrs="{'invisible' : [('server_type', '=', 'local')]}" string="Server Information">
<field name="server" colspan="2" attrs="{'required' : [('server_type', '!=', 'local')]}" />
<field name="port" required="1" attrs="{'required' : [('server_type', '!=', 'local')]}" />
<field name="is_ssl"/>
</group>
<group attrs="{'invisible' : [('type', '=', 'local')]}" string="Login Information">
<field name="user" attrs="{'required' : [('type', '!=', 'local')]}"/>
<field name="password" password="True" attrs="{'required' : [('type', '!=', 'local')]}"/>
<group attrs="{'invisible' : [('server_type', '=', 'local')]}" string="Login Information">
<field name="user" attrs="{'required' : [('server_type', '!=', 'local')]}"/>
<field name="password" password="True" attrs="{'required' : [('server_type', '!=', 'local')]}"/>
</group>
<group string="Actions to Perform on Incoming Mails">
<field name="object_id"/>
</group>
<group attrs="{'invisible' : [('type', '!=', 'local')]}" string="Configuration">
<group attrs="{'invisible' : [('server_type', '!=', 'local')]}" string="Configuration">
<field name="configuration" colspan="4"/>
<field name="script" colspan="4" widget="url"/>
</group>
@@ -75,8 +75,8 @@
<field name="arch" type="xml">
<search string="Search Incoming Mail Servers">
<field name="name" string="Incoming Mail Server"/>
<filter string="IMAP" name="imap" domain="[('type','=','imap')]" help="Server type IMAP."/>
<filter string="POP" name="pop" domain="[('type','=','pop')]" help="Server type POP."/>
<filter string="IMAP" name="imap" domain="[('server_type','=','imap')]" help="Server type IMAP."/>
<filter string="POP" name="pop" domain="[('server_type','=','pop')]" help="Server type POP."/>
<separator/>
<filter string="SSL" name="ssl" domain="[('is_ssl','=',True)]" help="If SSL required."/>
</search>
@@ -215,7 +215,7 @@ class GoogleCalendar(models.AbstractModel):
reminders = []
for alarm in event.alarm_ids:
reminders.append({
"method": "email" if alarm.type == "email" else "popup",
"method": "email" if alarm.alarm_type == "email" else "popup",
"minutes": alarm.duration_minutes
})
data = {
@@ -458,13 +458,13 @@ class GoogleCalendar(models.AbstractModel):
for google_alarm in single_event_dict.get('reminders', {}).get('overrides', []):
alarm = CalendarAlarm.search(
[
('type', '=', google_alarm['method'] if google_alarm['method'] == 'email' else 'notification'),
('alarm_type', '=', google_alarm['method'] if google_alarm['method'] == 'email' else 'notification'),
('duration_minutes', '=', google_alarm['minutes'])
], limit=1
)
if not alarm:
data = {
'type': google_alarm['method'] if google_alarm['method'] == 'email' else 'notification',
'alarm_type': google_alarm['method'] if google_alarm['method'] == 'email' else 'notification',
'duration': google_alarm['minutes'],
'interval': 'minutes',
'name': "%s minutes - %s" % (google_alarm['minutes'], google_alarm['method'])
+5 -5
View File
@@ -13,10 +13,10 @@ class LeaveReport(models.Model):
employee_id = fields.Many2one('hr.employee', string="Employee", readonly=True)
name = fields.Char('Description', readonly=True)
number_of_days = fields.Float('Number of Days', readonly=True)
type = fields.Selection([
leave_type = fields.Selection([
('allocation', 'Allocation Request'),
('request', 'Leave Request')
], string='Request Type', readonly=True)
], string='Request Type', readonly=True, oldname='type')
department_id = fields.Many2one('hr.department', string='Department', readonly=True)
category_id = fields.Many2one('hr.employee.category', string='Employee Tag', readonly=True)
holiday_status_id = fields.Many2one("hr.leave.type", string="Leave Type", readonly=True)
@@ -43,7 +43,7 @@ class LeaveReport(models.Model):
CREATE or REPLACE view hr_leave_report as (
SELECT row_number() over(ORDER BY leaves.employee_id) as id,
leaves.employee_id as employee_id, leaves.name as name,
leaves.number_of_days as number_of_days, leaves.type as type,
leaves.number_of_days as number_of_days, leaves.leave_type as leave_type,
leaves.category_id as category_id, leaves.department_id as department_id,
leaves.holiday_status_id as holiday_status_id, leaves.state as state,
leaves.holiday_type as holiday_type, leaves.date_from as date_from,
@@ -60,7 +60,7 @@ class LeaveReport(models.Model):
null as date_from,
null as date_to,
FALSE as payslip_status,
'allocation' as type
'allocation' as leave_type
from hr_leave_allocation as allocation
union all select
request.employee_id as employee_id,
@@ -74,7 +74,7 @@ class LeaveReport(models.Model):
request.date_from as date_from,
request.date_to as date_to,
request.payslip_status as payslip_status,
'request' as type
'request' as leave_type
from hr_leave as request) leaves
);
""")
@@ -49,7 +49,7 @@
<field name="date_from"/>
<field name="date_to"/>
<field name="state"/>
<field name="type"/>
<field name="leave_type"/>
<field name="name"/>
</tree>
</field>
@@ -20,13 +20,13 @@
<field name="page_id" ref="recruitment_1" />
<field name="sequence">1</field>
<field name="question">From which university will you graduate?</field>
<field name="type">textbox</field>
<field name="question_type">textbox</field>
</record>
<record id="recruitment_1_2" model="survey.question">
<field name="page_id" ref="recruitment_1" />
<field name="sequence">2</field>
<field name="question">What is your gender?</field>
<field name="type">simple_choice</field>
<field name="question_type">simple_choice</field>
<field name="display_mode">dropdown</field>
</record>
<record id="recruitment_1_2_1" model="survey.label">
@@ -43,7 +43,7 @@
<field name="page_id" ref="recruitment_1" />
<field name="sequence">3</field>
<field name="question">What age group do you belong to?</field>
<field name="type">simple_choice</field>
<field name="question_type">simple_choice</field>
<field name="display_mode">columns</field>
<field name="column_nb">4</field>
</record>
@@ -99,25 +99,25 @@
<field name="page_id" ref="recruitment_2" />
<field name="sequence">1</field>
<field name="question">Knowledge</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<record id="recruitment_2_2" model="survey.question">
<field name="page_id" ref="recruitment_2" />
<field name="sequence">2</field>
<field name="question">Education</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<record id="recruitment_2_3" model="survey.question">
<field name="page_id" ref="recruitment_2" />
<field name="sequence">3</field>
<field name="question">Experience</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<record id="recruitment_2_4" model="survey.question">
<field name="page_id" ref="recruitment_2" />
<field name="sequence">4</field>
<field name="question">Activities</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<!-- Page 3 -->
<record id="recruitment_3" model="survey.page">
@@ -130,7 +130,7 @@
<field name="page_id" ref="recruitment_3" />
<field name="sequence">1</field>
<field name="question">Rate the Importance</field>
<field name="type">matrix</field>
<field name="question_type">matrix</field>
<field name="matrix_subtype">simple</field>
</record>
<record id="rcol_3_1_1" model="survey.label">
+6 -6
View File
@@ -166,9 +166,9 @@ class Survey(http.Controller):
answer_value = None
if answer.answer_type == 'free_text':
answer_value = answer.value_free_text
elif answer.answer_type == 'text' and answer.question_id.type == 'textbox':
elif answer.answer_type == 'text' and answer.question_id.question_type == 'textbox':
answer_value = answer.value_text
elif answer.answer_type == 'text' and answer.question_id.type != 'textbox':
elif answer.answer_type == 'text' and answer.question_id.question_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
@@ -225,7 +225,7 @@ class Survey(http.Controller):
user_input = request.env['survey.user_input'].sudo().search([('token', '=', post['token'])], limit=1)
except KeyError: # Invalid token
return request.render("survey.403", {'survey': survey})
user_id = request.env.user.id if user_input.type != 'link' else SUPERUSER_ID
user_id = request.env.user.id if user_input.input_type != 'link' else SUPERUSER_ID
for question in questions:
answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
@@ -363,13 +363,13 @@ class Survey(http.Controller):
current_filters = current_filters if current_filters else []
Survey = request.env['survey.survey']
result = []
if question.type == 'multiple_choice':
if question.question_type == 'multiple_choice':
result.append({'key': ustr(question.question),
'values': Survey.prepare_result(question, current_filters)['answers']
})
if question.type == 'simple_choice':
if question.question_type == 'simple_choice':
result = Survey.prepare_result(question, current_filters)['answers']
if question.type == 'matrix':
if question.question_type == 'matrix':
data = Survey.prepare_result(question, current_filters)
for answer in data['answers']:
values = []
+13 -13
View File
@@ -21,7 +21,7 @@
<field name="page_id" ref="feedback_1" />
<field name="sequence">1</field>
<field name="question">Are you using Odoo on a daily basis?</field>
<field name="type">simple_choice</field>
<field name="question_type">simple_choice</field>
<field name="display_mode">dropdown</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -49,7 +49,7 @@
<field name="page_id" ref="feedback_1" />
<field name="sequence">2</field>
<field name="question">Which modules are you using/testing?</field>
<field name="type">multiple_choice</field>
<field name="question_type">multiple_choice</field>
<field name="column_nb">4</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -95,7 +95,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">1</field>
<field name="question">What do you think about the documentation available on doc.odoo.com?</field>
<field name="type">matrix</field>
<field name="question_type">matrix</field>
<field name="matrix_subtype">simple</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -148,7 +148,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">2</field>
<field name="question">What do you think about the process views of Odoo, available in the web client ?</field>
<field name="type">matrix</field>
<field name="question_type">matrix</field>
<field name="matrix_subtype">simple</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -201,13 +201,13 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">3</field>
<field name="question">Do you have suggestions on how to improve the process view ?</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<record model="survey.question" id="feedback_2_4">
<field name="page_id" ref="feedback_2" />
<field name="sequence">4</field>
<field name="question">What do you think about the structure of the menus?</field>
<field name="type">multiple_choice</field>
<field name="question_type">multiple_choice</field>
<field name="column_nb">4</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -230,7 +230,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">5</field>
<field name="question">What do you think about the groups of users?</field>
<field name="type">matrix</field>
<field name="question_type">matrix</field>
<field name="matrix_subtype">simple</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -283,7 +283,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">6</field>
<field name="question">What do you think about the structure of the menus?</field>
<field name="type">simple_choice</field>
<field name="question_type">simple_choice</field>
<field name="display_mode">columns</field>
<field name="column_nb">4</field>
<field name="constr_mandatory" eval="True" />
@@ -307,7 +307,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_2" />
<field name="sequence">7</field>
<field name="question">What do you think about configuration wizards?</field>
<field name="type">matrix</field>
<field name="question_type">matrix</field>
<field name="matrix_subtype">simple</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -362,7 +362,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_3" />
<field name="sequence">1</field>
<field name="question">How do you contribute or plan to contribute to Odoo?</field>
<field name="type">multiple_choice</field>
<field name="question_type">multiple_choice</field>
<field name="column_nb">6</field>
<field name="constr_mandatory" eval="True" />
</record>
@@ -395,13 +395,13 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_3" />
<field name="sequence">2</field>
<field name="question">Do you have a proposition to help people to contribute?</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<record model="survey.question" id="feedback_3_3">
<field name="page_id" ref="feedback_3" />
<field name="sequence">3</field>
<field name="question">Do you have a proposition to attract new contributors?</field>
<field name="type">free_text</field>
<field name="question_type">free_text</field>
</record>
<!-- Page 4 -->
<record model="survey.page" id="feedback_4">
@@ -414,7 +414,7 @@ what have been your difficulties.&lt;/p&gt;</field>
<field name="page_id" ref="feedback_4" />
<field name="sequence">1</field>
<field name="question">Where do you develop your new features?</field>
<field name="type">multiple_choice</field>
<field name="question_type">multiple_choice</field>
<field name="column_nb">6</field>
</record>
<record model="survey.label" id="choice_4_1_1">
+12 -12
View File
@@ -226,7 +226,7 @@ class Survey(models.Model):
result_summary = {}
# Calculate and return statistics for choice
if question.type in ['simple_choice', 'multiple_choice']:
if question.question_type in ['simple_choice', 'multiple_choice']:
comments = []
answers = OrderedDict((label.id, {'text': label.value, 'count': 0, 'answer_id': label.id}) for label in question.labels_ids)
for input_line in question.user_input_line_ids:
@@ -237,7 +237,7 @@ class Survey(models.Model):
result_summary = {'answers': list(answers.values()), 'comments': comments}
# Calculate and return statistics for matrix
if question.type == 'matrix':
if question.question_type == 'matrix':
rows = OrderedDict()
answers = OrderedDict()
res = dict()
@@ -254,14 +254,14 @@ class Survey(models.Model):
result_summary = {'answers': answers, 'rows': rows, 'result': res, 'comments': comments}
# Calculate and return statistics for free_text, textbox, date
if question.type in ['free_text', 'textbox', 'date']:
if question.question_type in ['free_text', 'textbox', 'date']:
result_summary = []
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
result_summary.append(input_line)
# Calculate and return statistics for numerical_box
if question.type == 'numerical_box':
if question.question_type == 'numerical_box':
result_summary = {'input_lines': []}
all_inputs = []
for input_line in question.user_input_line_ids:
@@ -434,14 +434,14 @@ class SurveyQuestion(models.Model):
oldname='descriptive_text')
# Answer
type = fields.Selection([
question_type = fields.Selection([
('free_text', 'Multiple Lines Text Box'),
('textbox', 'Single Line Text Box'),
('numerical_box', 'Numerical Value'),
('date', 'Date'),
('simple_choice', 'Multiple choice: only one answer'),
('multiple_choice', 'Multiple choice: multiple answers allowed'),
('matrix', 'Matrix')], string='Type of Question', default='free_text', required=True)
('matrix', 'Matrix')], string='Type of Question', default='free_text', required=True, oldname='type')
matrix_subtype = fields.Selection([('simple', 'One choice per row'),
('multiple', 'Multiple choices per row')], string='Matrix Type', default='simple')
labels_ids = fields.One2many('survey.label', 'question_id', string='Types of answers', oldname='answer_choice_ids', copy=True)
@@ -509,9 +509,9 @@ class SurveyQuestion(models.Model):
""" Validate question, depending on question type and parameters """
self.ensure_one()
try:
checker = getattr(self, 'validate_' + self.type)
checker = getattr(self, 'validate_' + self.question_type)
except AttributeError:
_logger.warning(self.type + ": This type of question has no validation method")
_logger.warning(self.question_type + ": This type of question has no validation method")
return {}
else:
return checker(post, answer_tag)
@@ -698,7 +698,7 @@ class SurveyUserInput(models.Model):
survey_id = fields.Many2one('survey.survey', string='Survey', required=True, readonly=True, ondelete='restrict')
date_create = fields.Datetime('Creation Date', default=fields.Datetime.now, required=True, readonly=True, copy=False)
deadline = fields.Datetime('Deadline', help="Date by which the person can open the survey and submit answers", oldname="date_deadline")
type = fields.Selection([('manually', 'Manually'), ('link', 'Link')], string='Answer Type', default='manually', required=True, readonly=True, oldname="response_type")
input_type = fields.Selection([('manually', 'Manually'), ('link', 'Link')], string='Answer Type', default='manually', required=True, readonly=True, oldname="type")
state = fields.Selection([
('new', 'Not started yet'),
('skip', 'Partially completed'),
@@ -736,7 +736,7 @@ class SurveyUserInput(models.Model):
(used as a cronjob declared in data/survey_cron.xml)
"""
an_hour_ago = fields.Datetime.to_string(datetime.datetime.now() - datetime.timedelta(hours=1))
self.search([('type', '=', 'manually'), ('state', '=', 'new'),
self.search([('input_type', '=', 'manually'), ('state', '=', 'new'),
('date_create', '<', an_hour_ago)]).unlink()
@api.multi
@@ -846,9 +846,9 @@ class SurveyUserInputLine(models.Model):
overwritten (in order to maintain data consistency).
"""
try:
saver = getattr(self, 'save_line_' + question.type)
saver = getattr(self, 'save_line_' + question.question_type)
except AttributeError:
_logger.error(question.type + ": This type of question has no saving function")
_logger.error(question.question_type + ": This type of question has no saving function")
return False
else:
saver(user_input_id, question, post, answer_tag)
+16 -16
View File
@@ -43,8 +43,8 @@ class TestSurvey(TransactionCase):
self.assertEqual(question.question, "Q0", msg="Title of the Question is somehow modified.")
def test_01_question_type_validation_save_line_function(self):
for (question_type, text) in self.env['survey.question']._fields['type'].selection:
# Each question ype must have validation function.
for (question_type, text) in self.env['survey.question']._fields['question_type'].selection:
# Each question type must have validation function.
self.assertTrue(hasattr(self.env['survey.question'], 'validate_' + question_type), msg="Question must have a validation method in\
the form of 'validate_' followed by the name of the type.")
@@ -53,24 +53,24 @@ class TestSurvey(TransactionCase):
the form of 'save_line_' followed by the name of the type.")
def test_02_question_answer_required(self):
for (question_type, text) in self.env['survey.question']._fields['type'].selection:
for (question_type, text) in self.env['survey.question']._fields['question_type'].selection:
# Blank value of field is not accepted for mandatory questions.
if question_type == 'multiple_choice':
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'multiple_choice',
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'multiple_choice',
'constr_mandatory': True, 'constr_error_msg': 'Error',
'labels_ids': [(0, 0, {'value': "MChoice0", "quizz_mark": 0}), (0, 0, {'value': "MChoice1", "quizz_mark": 0})]})
elif question_type == 'matrix':
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'matrix', 'matrix_subtype': 'simple',
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'matrix', 'matrix_subtype': 'simple',
'constr_mandatory': True, 'constr_error_msg': 'Error',
'labels_ids': [(0, 0, {'value': "Column0", "quizz_mark": 0}), (0, 0, {'value': "Column1", "quizz_mark": 0})],
'labels_ids_2': [(0, 0, {'value': "Row0", "quizz_mark": 0}), (0, 0, {'value': "Row1", "quizz_mark": 0})]})
else:
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': question_type, 'constr_mandatory': True, 'constr_error_msg': 'Error'})
'page_id': self.page1.id, 'question': 'Q0', 'question_type': question_type, 'constr_mandatory': True, 'constr_error_msg': 'Error'})
answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id)
self.assertDictEqual({answer_tag: "Error"}, question.validate_question({answer_tag: ''}, answer_tag),
msg=("Validation function for type %s is unable to generate error if it is mandatory and answer is blank." % question_type))
@@ -78,9 +78,9 @@ class TestSurvey(TransactionCase):
def test_03_question_textbox(self):
questions = [
self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'textbox', 'validation_email': True}),
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'textbox', 'validation_email': True}),
self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q1', 'type': 'textbox', 'validation_required': True,
'page_id': self.page1.id, 'question': 'Q1', 'question_type': 'textbox', 'validation_required': True,
'validation_length_min': 2, 'validation_length_max': 8, 'validation_error_msg': "Error"})]
results = [('test @ testcom', _('This answer must be an email address')), ('t', 'Error')]
@@ -91,7 +91,7 @@ class TestSurvey(TransactionCase):
def test_04_question_numerical_box(self):
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box', 'validation_required': True,
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'numerical_box', 'validation_required': True,
'validation_min_float_value': 2.1, 'validation_max_float_value': 3.0, 'validation_error_msg': "Error"})
answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id)
results = [('aaa', _('This is not a number')), ('4.5', 'Error'), ('0.1', 'Error')]
@@ -101,7 +101,7 @@ class TestSurvey(TransactionCase):
def test_05_question_date(self):
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'date', 'validation_required': True,
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'date', 'validation_required': True,
'validation_min_date': '2015-03-20', 'validation_max_date': '2015-03-25', 'validation_error_msg': "Error"})
answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id)
results = [('2015-55-10', _('This is not a date')), ('2015-03-19', 'Error'), ('2015-03-26', 'Error')]
@@ -113,7 +113,7 @@ class TestSurvey(TransactionCase):
# Case-1: Executing action with correct data.
correct_survey = self.env['survey.survey'].sudo(self.survey_manager).create({
'title': "S0", 'stage_id': self.env['survey.stage'].search([('sequence', '=', 1)]).id,
'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'type': 'free_text'})]})]})
'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'question_type': 'free_text'})]})]})
action = correct_survey.action_send_survey()
template = self.env.ref('survey.email_template_survey', raise_if_not_found=False)
@@ -143,7 +143,7 @@ class TestSurvey(TransactionCase):
'title': "Test survey"}),
self.env['survey.survey'].sudo(self.survey_manager).create({ # Closed Survey.
'title': "S0", 'stage_id': self.env['survey.stage'].search([('closed', '=', True)]).id, # Getting Closed stage id.
'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'type': 'free_text'})]})]})]
'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'question_type': 'free_text'})]})]})]
for survey in surveys:
self.assertRaises(UserError, survey.action_send_survey)
@@ -215,7 +215,7 @@ class TestSurvey(TransactionCase):
def test_10_survey_result_simple_multiple_choice(self):
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'simple_choice',
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'simple_choice',
'labels_ids': [(0, 0, {'value': "Choice0", 'quizz_mark': 0}), (0, 0, {'value': "Choice1", 'quizz_mark': 0})]})
for i in range(3):
self.env['survey.user_input'].sudo(self.user_public).create({'survey_id': self.survey1.id, 'user_input_line_ids': [(0, 0, {
@@ -229,7 +229,7 @@ class TestSurvey(TransactionCase):
def test_11_survey_result_matrix(self):
question = self.env['survey.question'].sudo(self.survey_manager).create({
'page_id': self.page1.id, 'question': 'Q0', 'type': 'matrix', 'matrix_subtype': 'simple',
'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'matrix', 'matrix_subtype': 'simple',
'labels_ids': [(0, 0, {'value': "Column0", "quizz_mark": 0}), (0, 0, {'value': "Column1", "quizz_mark": 0})],
'labels_ids_2': [(0, 0, {'value': "Row0", "quizz_mark": 0}), (0, 0, {'value': "Row1", "quizz_mark": 0})]})
for i in range(3):
@@ -243,7 +243,7 @@ class TestSurvey(TransactionCase):
self.assertEqual(self.env['survey.survey'].prepare_result(question)['result'], res, msg="Statistics of matrix type questions are different from expectations")
def test_12_survey_result_numeric_box(self):
question = self.env['survey.question'].sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box'})
question = self.env['survey.question'].sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'numerical_box'})
num = [float(n) for n in random.sample(range(1, 100), 3)]
nsum = sum(num)
for i in range(3):
@@ -257,7 +257,7 @@ class TestSurvey(TransactionCase):
self.assertEqual(result[key], exresult[key], msg="Statistics of numeric box type questions are different from expectations")
def test_13_survey_actions(self):
self.env['survey.question'].sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box'})
self.env['survey.question'].sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'question_type': 'numerical_box'})
actions = {
'start': {'method': 'public', 'token': '/test', 'text': 'Start'},
+14 -14
View File
@@ -37,11 +37,11 @@
<h4>
<b>Question </b>
<span t-field='question.question'></span>
<t t-if="question.type == 'matrix'">
<t t-if="question.question_type == 'matrix'">
<small><span class="badge badge-secondary">Matrix: <span t-field='question.matrix_subtype'/></span></small>
</t>
<t t-if="question.type in ['simple_choice', 'multiple_choice']">
<small><span t-field='question.type' class="badge badge-secondary"></span></small>
<t t-if="question.question_type in ['simple_choice', 'multiple_choice']">
<small><span t-field='question.question_type' class="badge badge-secondary"></span></small>
</t>
<span class="float-right">
<span class="badge badge-success"><span t-esc="input_summary['answered']"></span> Answered</span>
@@ -52,16 +52,16 @@
<t t-if="question.description">
<div class="text-muted oe_no_empty" t-field="question.description" />
</t>
<t t-if="question.type in ['textbox', 'free_text', 'date']">
<t t-if="question.question_type in ['textbox', 'free_text', 'date']">
<t t-call="survey.result_text"></t>
</t>
<t t-if="question.type in ['simple_choice', 'multiple_choice']">
<t t-if="question.question_type in ['simple_choice', 'multiple_choice']">
<t t-call="survey.result_choice"></t>
</t>
<t t-if="question.type == 'matrix'">
<t t-if="question.question_type == 'matrix'">
<t t-call="survey.result_matrix"></t>
</t>
<t t-if="question.type == 'numerical_box'">
<t t-if="question.question_type == 'numerical_box'">
<t t-call="survey.result_number"></t>
</t>
</t>
@@ -88,17 +88,17 @@
<t t-set="text_result" t-value="prepare_result"/>
<tr t-foreach="text_result" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<t t-if="question.type == 'free_text'">
<t t-if="question.question_type == 'free_text'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_free_text"></a><br/>
</td>
</t>
<t t-if="question.type == 'textbox'">
<t t-if="question.question_type == 'textbox'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_text"></a><br/>
</td>
</t>
<t t-if="question.type == 'date'">
<t t-if="question.question_type == 'date'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_date"></a><br/>
</td>
@@ -136,12 +136,12 @@
<div>
<!-- Tabs -->
<ul class="nav nav-tabs d-print-none" role="tablist">
<li class="nav-item" t-if="question.type != 'simple_choice'">
<li class="nav-item" t-if="question.question_type != 'simple_choice'">
<a t-att-href="'#graph_question_%d' % question.id" t-att-aria-controls="'graph_question_%d' % question.id" class="nav-link active" data-toggle="tab" role="tab">
<i class="fa fa-bar-chart-o"></i> Graph
</a>
</li>
<li class="nav-item" t-if="question.type == 'simple_choice'">
<li class="nav-item" t-if="question.question_type == 'simple_choice'">
<a t-att-href="'#graph_question_%d' % question.id" t-att-aria-controls="'graph_question_%d' % question.id" class="nav-link active" data-toggle="tab" role="tab">
<i class="fa fa-bar-chart-o"></i> Pie Chart
</a>
@@ -153,11 +153,11 @@
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active survey_graph" t-if="question.type != 'simple_choice'" t-att-id="'graph_question_%d' % question.id" t-att-data-question_id="question.id" data-graph_type="bar" t-att-graph-data="graph_data">
<div role="tabpanel" class="tab-pane active survey_graph" t-if="question.question_type != 'simple_choice'" t-att-id="'graph_question_%d' % question.id" t-att-data-question_id="question.id" data-graph_type="bar" t-att-graph-data="graph_data">
<!-- svg element for drawing bar chart -->
<svg style="height:20em"></svg>
</div>
<div role="tabpanel" class="tab-pane active survey_graph" t-if="question.type == 'simple_choice'" t-att-id="'graph_question_%d' % question.id" t-att-data-question_id="question.id" data-graph_type="pie" t-att-graph-data="graph_data">
<div role="tabpanel" class="tab-pane active survey_graph" t-if="question.question_type == 'simple_choice'" t-att-id="'graph_question_%d' % question.id" t-att-data-question_id="question.id" data-graph_type="pie" t-att-graph-data="graph_data">
<!-- svg element for drawing pie chart -->
<svg style="height:20em"></svg>
</div>
+14 -14
View File
@@ -190,13 +190,13 @@
<span t-if="question.constr_mandatory" class="text-danger">*</span>
</h2>
<div t-field='question.description' class="text-muted oe_no_empty"/>
<t t-if="question.type == 'free_text'"><t t-call="survey.free_text"/></t>
<t t-if="question.type == 'textbox'"><t t-call="survey.textbox"/></t>
<t t-if="question.type == 'numerical_box'"><t t-call="survey.numerical_box"/></t>
<t t-if="question.type == 'date'"><t t-call="survey.date"/></t>
<t t-if="question.type == 'simple_choice'"><t t-call="survey.simple_choice"/></t>
<t t-if="question.type == 'multiple_choice'"><t t-call="survey.multiple_choice"/></t>
<t t-if="question.type == 'matrix'"><t t-call="survey.matrix"/></t>
<t t-if="question.question_type == 'free_text'"><t t-call="survey.free_text"/></t>
<t t-if="question.question_type == 'textbox'"><t t-call="survey.textbox"/></t>
<t t-if="question.question_type == 'numerical_box'"><t t-call="survey.numerical_box"/></t>
<t t-if="question.question_type == 'date'"><t t-call="survey.date"/></t>
<t t-if="question.question_type == 'simple_choice'"><t t-call="survey.simple_choice"/></t>
<t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.multiple_choice"/></t>
<t t-if="question.question_type == 'matrix'"><t t-call="survey.matrix"/></t>
<div class="js_errzone alert alert-danger" style="display:none;" role="alert"></div>
</div>
</t>
@@ -356,13 +356,13 @@
<span t-if="quizz_correction" class="badge badge-pill" t-att-data-score-question="question.id"></span>
</h2>
<t t-if="question.description"><div class="text-muted oe_no_empty" t-field='question.description'/></t>
<t t-if="question.type == 'free_text'"><t t-call="survey.free_text"/></t>
<t t-if="question.type == 'textbox'"><t t-call="survey.textbox"/></t>
<t t-if="question.type == 'numerical_box'"><t t-call="survey.numerical_box"/></t>
<t t-if="question.type == 'date'"><t t-call="survey.date"/></t>
<t t-if="question.type == 'simple_choice'"><t t-call="survey.simple_choice"/></t>
<t t-if="question.type == 'multiple_choice'"><t t-call="survey.multiple_choice"/></t>
<t t-if="question.type == 'matrix'"><t t-call="survey.matrix"/></t>
<t t-if="question.question_type == 'free_text'"><t t-call="survey.free_text"/></t>
<t t-if="question.question_type == 'textbox'"><t t-call="survey.textbox"/></t>
<t t-if="question.question_type == 'numerical_box'"><t t-call="survey.numerical_box"/></t>
<t t-if="question.question_type == 'date'"><t t-call="survey.date"/></t>
<t t-if="question.question_type == 'simple_choice'"><t t-call="survey.simple_choice"/></t>
<t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.multiple_choice"/></t>
<t t-if="question.question_type == 'matrix'"><t t-call="survey.matrix"/></t>
<div class="js_errzone alert alert-danger" style="display:none;" role="alert"></div>
</div>
</t>
+36 -36
View File
@@ -30,7 +30,7 @@
<field name="arch" type="xml">
<form string="Survey User inputs" create="false">
<header>
<button name="action_survey_resend" string="Send Invitation Again" type="object" class="oe_highlight" attrs="{'invisible': ['|', ('type','=','manually'), ('state', '=', 'done')]}"/>
<button name="action_survey_resend" string="Send Invitation Again" type="object" class="oe_highlight" attrs="{'invisible': ['|', ('input_type','=','manually'), ('state', '=', 'done')]}"/>
<button name="action_view_answers" states="done" string="Print These Answers" type="object" class="oe_highlight" />
<button name="action_survey_results" string="View Results" type="object" />
<field name="state" widget="statusbar"/>
@@ -41,7 +41,7 @@
<group>
<field name="survey_id"/>
<field name="date_create"/>
<field name="type"/>
<field name="input_type"/>
<field name="token" groups="base.group_no_one"/>
</group>
<group>
@@ -76,7 +76,7 @@
<field name="deadline"/>
<field name="partner_id"/>
<field name="email"/>
<field name="type"/>
<field name="input_type"/>
<field name="state"/>
<field name="test_entry" invisible="True"/>
<field name="quizz_score" groups="base.group_no_one"/>
@@ -93,7 +93,7 @@
<field name="date_create"/>
<field name="partner_id"/>
<field name="email"/>
<field name="type"/>
<field name="input_type"/>
<field name="state"/>
<templates>
<t t-name="kanban-box">
@@ -102,7 +102,7 @@
<div class="o_kanban_record_headings">
<strong class="o_kanban_record_title"><t t-esc="record.survey_id.value"/></strong>
</div>
<span class="badge badge-pill"><t t-esc="record.type.value"/></span>
<span class="badge badge-pill"><t t-esc="record.input_type.value"/></span>
</div>
<div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left">
@@ -337,7 +337,7 @@
<tree>
<field name="sequence" widget="handle"/>
<field name="question"/>
<field name="type"/>
<field name="question_type"/>
<field name="constr_mandatory"/>
</tree>
</field>
@@ -406,42 +406,42 @@
</div>
<group>
<group>
<field name="type" widget="radio" />
<field name="question_type" widget="radio" />
</group>
<group>
<div class="col-lg-6 offset-lg-3 o_preview_questions">
<!-- Multiple Lines Text Zone -->
<div attrs="{'invisible': [('type', '!=', 'free_text')]}">
<div attrs="{'invisible': [('question_type', '!=', 'free_text')]}">
<i class="fa fa-align-justify fa-4x" role="img" aria-label="Multiple lines" title="Multiple Lines"/>
</div>
<!-- Single Line Text Zone -->
<div attrs="{'invisible': [('type', '!=', 'textbox')]}">
<div attrs="{'invisible': [('question_type', '!=', 'textbox')]}">
<i class="fa fa-minus fa-4x" role="img" aria-label="Single Line" title="Single Line"/>
</div>
<!-- Numerical Value -->
<div attrs="{'invisible': [('type', '!=', 'numerical_box')]}">
<div attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}">
<i class="fa fa-2x" role="img" aria-label="Numeric" title="Numeric">123..</i>
</div>
<!-- Date and Time -->
<div attrs="{'invisible': [('type', '!=', 'date')]}">
<div attrs="{'invisible': [('question_type', '!=', 'date')]}">
<p class="o_datetime">YYYY-MM-DD
<i class="fa fa-calendar fa-2x" role="img" aria-label="Calendar" title="Calendar"/>
</p>
</div>
<!-- Multiple choice: only one answer -->
<div attrs="{'invisible': [('type', '!=', 'simple_choice')]}" role="img" aria-label="Multiple choice with one answer" title="Multiple choice with one answer">
<div attrs="{'invisible': [('question_type', '!=', 'simple_choice')]}" role="img" aria-label="Multiple choice with one answer" title="Multiple choice with one answer">
<div class="row"><i class="fa fa-circle-o fa-lg"/> answer</div>
<div class="row"><i class="fa fa-dot-circle-o fa-lg"/> answer</div>
<div class="row"><i class="fa fa-circle-o fa-lg"/> answer</div>
</div>
<!-- Multiple choice: multiple answers allowed -->
<div attrs="{'invisible': [('type', '!=', 'multiple_choice')]}" role="img" aria-label="Multiple choice with multiple answers" title="Multiple choice with multiple answers">
<div attrs="{'invisible': [('question_type', '!=', 'multiple_choice')]}" role="img" aria-label="Multiple choice with multiple answers" title="Multiple choice with multiple answers">
<div class="row"><i class="fa fa-square-o fa-lg"/> answer</div>
<div class="row"><i class="fa fa-check-square-o fa-lg"/> answer</div>
<div class="row"><i class="fa fa-square-o fa-lg"/> answer</div>
</div>
<!-- Matrix -->
<div attrs="{'invisible': [('type', '!=', 'matrix')]}">
<div attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
<div class="row o_matrix_head">
<div class="col-lg-3"></div>
<div class="col-lg-3">ans</div>
@@ -472,10 +472,10 @@
</group>
<notebook>
<page string="Answers">
<field name="validation_email" attrs="{'invisible': [('type', '!=', 'textbox')]}"/>
<label for="validation_email" attrs="{'invisible': [('type', '!=', 'textbox')]}"/>
<field name="validation_email" attrs="{'invisible': [('question_type', '!=', 'textbox')]}"/>
<label for="validation_email" attrs="{'invisible': [('question_type', '!=', 'textbox')]}"/>
<separator />
<field name="labels_ids" string="Type of answers" context="{'default_question_id': active_id}" attrs="{'invisible': [('type', 'not in', ['simple_choice', 'multiple_choice', 'matrix'])]}">
<field name="labels_ids" string="Type of answers" context="{'default_question_id': active_id}" attrs="{'invisible': [('question_type', 'not in', ['simple_choice', 'multiple_choice', 'matrix'])]}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="value" string="Choices"/>
@@ -483,8 +483,8 @@
</tree>
</field>
<separator />
<label for="labels_ids_2" attrs="{'invisible': [('type', '!=', 'matrix')]}" />
<field name="labels_ids_2" context="{'default_question_id_2': active_id}" attrs="{'invisible': [('type', '!=', 'matrix')]}">
<label for="labels_ids_2" attrs="{'invisible': [('question_type', '!=', 'matrix')]}" />
<field name="labels_ids_2" context="{'default_question_id_2': active_id}" attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="value" string="Rows"/>
@@ -497,32 +497,32 @@
<field name="constr_mandatory" string="Mandatory Answer"/>
<field name="constr_error_msg" attrs="{'invisible': [('constr_mandatory', '=', False)]}"/>
</group>
<div colspan="2" attrs="{'invisible': [('type', 'not in', ['textbox', 'numerical_box', 'date'])]}">
<div colspan="2" attrs="{'invisible': [('question_type', 'not in', ['textbox', 'numerical_box', 'date'])]}">
<group>
<field name="validation_required" attrs="{'invisible': [('validation_email', '=', True), ('type', '=', 'textbox')]}"/>
<field name="validation_required" attrs="{'invisible': [('validation_email', '=', True), ('question_type', '=', 'textbox')]}"/>
</group>
<group col="4" attrs="{'invisible': [('validation_required', '=', False)]}">
<field name="validation_length_min" attrs="{'invisible': [('type', '!=', 'textbox')]}"/>
<field name="validation_length_max" attrs="{'invisible': [('type', '!=', 'textbox')]}"/>
<field name="validation_min_float_value" attrs="{'invisible': [('type', '!=', 'numerical_box')]}"/>
<field name="validation_max_float_value" attrs="{'invisible': [('type', '!=', 'numerical_box')]}"/>
<field name="validation_min_date" attrs="{'invisible': [('type', '!=', 'date')]}"/>
<field name="validation_max_date" attrs="{'invisible': [('type', '!=', 'date')]}"/>
<field name="validation_length_min" attrs="{'invisible': [('question_type', '!=', 'textbox')]}"/>
<field name="validation_length_max" attrs="{'invisible': [('question_type', '!=', 'textbox')]}"/>
<field name="validation_min_float_value" attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}"/>
<field name="validation_max_float_value" attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}"/>
<field name="validation_min_date" attrs="{'invisible': [('question_type', '!=', 'date')]}"/>
<field name="validation_max_date" attrs="{'invisible': [('question_type', '!=', 'date')]}"/>
<field name="validation_error_msg" colspan="4"/>
</group>
</div>
<group>
<field name="matrix_subtype" attrs="{'invisible':[('type','not in',['matrix'])]}"/>
<field name="matrix_subtype" attrs="{'invisible':[('question_type','not in',['matrix'])]}"/>
</group>
</group>
<group string="Display mode" attrs="{'invisible':[('type','not in',['simple_choice', 'multiple_choice'])]}">
<field name="display_mode" string="Format" attrs="{'invisible':[('type','not in',['simple_choice'])],'required':[('type','=','simple_choice')]}"/>
<field name="column_nb" string="Number of columns" attrs="{'invisible':[('display_mode','=','dropdown'), ('type','=','simple_choice')]}"/>
<group string="Display mode" attrs="{'invisible':[('question_type','not in',['simple_choice', 'multiple_choice'])]}">
<field name="display_mode" string="Format" attrs="{'invisible':[('question_type','not in',['simple_choice'])],'required':[('question_type','=','simple_choice')]}"/>
<field name="column_nb" string="Number of columns" attrs="{'invisible':[('display_mode','=','dropdown'), ('question_type','=','simple_choice')]}"/>
</group>
<group string="Allow Comments" attrs="{'invisible':[('type','not in',['simple_choice','multiple_choice', 'matrix'])]}">
<group string="Allow Comments" attrs="{'invisible':[('question_type','not in',['simple_choice','multiple_choice', 'matrix'])]}">
<field name='comments_allowed' />
<field name='comments_message' attrs="{'invisible': [('comments_allowed', '=', False)]}"/>
<field name='comment_count_as_answer' attrs="{'invisible': ['|', ('comments_allowed', '=', False), ('type', 'in', ['matrix'])]}" />
<field name='comment_count_as_answer' attrs="{'invisible': ['|', ('comments_allowed', '=', False), ('question_type', 'in', ['matrix'])]}" />
</group>
</page>
</notebook>
@@ -539,7 +539,7 @@
<field name="question"/>
<field name="page_id"/>
<field name="survey_id"/>
<field name="type"/>
<field name="question_type"/>
</tree>
</field>
</record>
@@ -551,10 +551,10 @@
<field name="question" string="Question"/>
<field name="survey_id" string="Survey"/>
<field name="page_id" string="Page"/>
<field name="type" string="Type"/>
<field name="question_type" string="Type"/>
<group expand="1" string="Group By">
<filter name="group_by_page" string="Page" domain="[]" context="{'group_by':'page_id'}"/>
<filter name="group_by_type" string="Type" domain="[]" context="{'group_by':'type'}"/>
<filter name="group_by_type" string="Type" domain="[]" context="{'group_by':'question_type'}"/>
</group>
</search>
</field>
@@ -150,7 +150,7 @@ class SurveyMailComposeMessage(models.TransientModel):
'survey_id': wizard.survey_id.id,
'deadline': wizard.date_deadline,
'date_create': fields.Datetime.now(),
'type': 'link',
'input_type': 'link',
'state': 'new',
'token': token,
'partner_id': partner_id,
+6 -6
View File
@@ -601,11 +601,11 @@ class IrServerObjectLines(models.Model):
"When Formula type is selected, this field may be a Python expression "
" that can use the same values as for the code field on the server action.\n"
"If Value type is selected, the value will be used directly without evaluation.")
type = fields.Selection([
evaluation_type = fields.Selection([
('value', 'Value'),
('reference', 'Reference'),
('equation', 'Python expression')
], 'Evaluation Type', default='value', required=True, change_default=True)
], 'Evaluation Type', default='value', required=True, change_default=True, oldname='type')
resource_ref = fields.Reference(
string='Record', selection='_selection_target_model',
compute='_compute_resource_ref', inverse='_set_resource_ref')
@@ -615,10 +615,10 @@ class IrServerObjectLines(models.Model):
models = self.env['ir.model'].search([])
return [(model.model, model.name) for model in models]
@api.depends('col1.relation', 'value', 'type')
@api.depends('col1.relation', 'value', 'evaluation_type')
def _compute_resource_ref(self):
for line in self:
if line.type in ['reference', 'value'] and line.col1 and line.col1.relation:
if line.evaluation_type in ['reference', 'value'] and line.col1 and line.col1.relation:
value = line.value or ''
try:
value = int(value)
@@ -634,7 +634,7 @@ class IrServerObjectLines(models.Model):
@api.onchange('resource_ref')
def _set_resource_ref(self):
for line in self.filtered(lambda line: line.type == 'reference'):
for line in self.filtered(lambda line: line.evaluation_type == 'reference'):
if line.resource_ref:
line.value = str(line.resource_ref.id)
@@ -643,7 +643,7 @@ class IrServerObjectLines(models.Model):
result = dict.fromkeys(self.ids, False)
for line in self:
expr = line.value
if line.type == 'equation':
if line.evaluation_type == 'equation':
expr = safe_eval(line.value, eval_context)
elif line.col1.ttype in ['many2one', 'integer']:
try:
+1 -1
View File
@@ -10,7 +10,7 @@ class IrLogging(models.Model):
create_date = fields.Datetime(readonly=True)
create_uid = fields.Integer(string='Uid', readonly=True) # Integer not m2o is intentionnal
name = fields.Char(required=True)
type = fields.Selection([('client', 'Client'), ('server', 'Server')], required=True, index=True)
logging_type = fields.Selection([('client', 'Client'), ('server', 'Server')], string='Type', required=True, index=True, oldname='type')
dbname = fields.Char(string='Database Name', index=True)
level = fields.Char(index=True)
message = fields.Text(required=True)
+2 -2
View File
@@ -105,8 +105,8 @@ class TestServerActions(TestServerActionsBase):
'crud_model_id': self.res_country_model.id,
'link_field_id': False,
'fields_lines': [(5,),
(0, 0, {'col1': self.res_country_name_field.id, 'value': 'record.name', 'type': 'equation'}),
(0, 0, {'col1': self.res_country_code_field.id, 'value': 'record.name[0:2]', 'type': 'equation'})],
(0, 0, {'col1': self.res_country_name_field.id, 'value': 'record.name', 'evaluation_type': 'equation'}),
(0, 0, {'col1': self.res_country_code_field.id, 'value': 'record.name[0:2]', 'evaluation_type': 'equation'})],
})
run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
+3 -3
View File
@@ -302,9 +302,9 @@
<field name="fields_lines">
<tree string="Field Mappings" editable="bottom">
<field name="col1" domain="['|', ('model_id', '=', parent.crud_model_id), ('model_id', '=', parent.model_id)]"/>
<field name="type"/>
<field name="resource_ref" attrs="{'readonly': [('type', '!=', 'reference')]}" options="{'hide_model': True}"/>
<field name="value" attrs="{'readonly': [('type', '=', 'reference')]}" force_save="1"/>
<field name="evaluation_type"/>
<field name="resource_ref" attrs="{'readonly': [('evaluation_type', '!=', 'reference')]}" options="{'hide_model': True}"/>
<field name="value" attrs="{'readonly': [('evaluation_type', '=', 'reference')]}" force_save="1"/>
</tree>
</field>
</page>
+4 -4
View File
@@ -7,7 +7,7 @@
<group>
<field name="create_date" />
<field name="dbname" />
<field name="type" />
<field name="logging_type" />
<field name="name" />
<field name="level" />
<field name="path" />
@@ -25,7 +25,7 @@
<field name="create_date" />
<field name="create_uid" />
<field name="dbname" />
<field name="type" />
<field name="logging_type" />
<field name="name" />
<field name="level" />
<field name="path" />
@@ -39,14 +39,14 @@
<field name="arch" type="xml">
<search string="Logs">
<field name="dbname" />
<field name="type" />
<field name="logging_type" />
<field name="name" />
<field name="level" />
<field name="message" />
<group expand="0" string="Group By">
<filter string="Database" name="database" domain="[]" context="{'group_by': 'dbname'}" />
<filter string="Level" name="group_by_level" domain="[]" context="{'group_by': 'level'}" />
<filter string="Type" name="group_by_type" domain="[]" context="{'group_by': 'type'}" />
<filter string="Type" name="group_by_type" domain="[]" context="{'group_by': 'logging_type'}" />
<filter string="Creation Date" name="group_by_month" domain="[]" context="{'group_by': 'create_date'}" />
</group>
</search>