Files
project_v19/sh_survey_extra_fields/controllers/controllers.py
T
2026-07-01 14:41:49 +07:00

164 lines
6.3 KiB
Python

# Part of Softhealer Technologies.
from odoo import http
from odoo.http import request
from odoo.exceptions import AccessError, MissingError
class SurveyController(http.Controller):
@http.route(['/survey/get_many2many_field_data'], type='json', auth="public", methods=['POST'])
def get_many2many_field_data(self, **kw):
records = []
rec_name = 'display_name' # Default fallback
model_name = False
if kw.get("model_id"):
try:
model_record = request.env["ir.model"].sudo().browse(int(kw.get("model_id")))
if model_record.exists():
model_name = model_record.model
# Use the model's defined _rec_name, fallback to display_name
rec_name = model_record._rec_name or 'display_name'
# Search records. Note: Using sudo() because this is a public route.
# Ensure the model has appropriate access rights for public users if possible.
records = request.env[model_name].sudo().search_read(
[],
fields=[rec_name, 'id'],
order=rec_name # Optional: Order by name for better UX
)
# Rename the rec_name field to 'name' for JS consistency
if records:
for record in records:
record['name'] = record.pop(rec_name, '')
except Exception as e:
# Log error in production, return empty in dev
pass
return {
'records': records,
'rec_name': rec_name,
'model_name': model_name,
}
@http.route(['/survey/get_many2one_field_data'], type='json', auth="public", methods=['POST'])
def get_many2one_field_data(self, **kw):
records = []
rec_name = 'display_name' # Default fallback
model_name = False
if kw.get("model_id"):
try:
model_record = request.env["ir.model"].sudo().browse(int(kw.get("model_id")))
if model_record.exists():
model_name = model_record.model
rec_name = model_record._rec_name or 'display_name'
records = request.env[model_name].sudo().search_read(
[],
fields=[rec_name, 'id'],
order=rec_name
)
if records:
for record in records:
record['name'] = record.pop(rec_name, '')
except Exception as e:
pass
return {
'records': records,
'rec_name': rec_name,
'model_name': model_name,
}
@http.route(['/survey/get_countries'], type='json', auth="public", methods=['POST'], csrf=False)
def get_countries(self, **kw):
"""
Returns list of countries and their states.
Optimized to fetch states in one go instead of per-country.
"""
countries = request.env["res.country"].sudo().search_read(
[],
fields=['name', 'id', 'code'],
order='name'
)
# Fetch all states at once for performance
all_states = request.env["res.country.state"].sudo().search_read(
[],
fields=['name', 'id', 'country_id', 'code'],
order='name'
)
# Group states by country_id for easier JS consumption
states_by_country = {}
for state in all_states:
country_id = state.get('country_id', [False])[0] if isinstance(state.get('country_id'),
list) else state.get('country_id')
if country_id:
if country_id not in states_by_country:
states_by_country[country_id] = []
states_by_country[country_id].append({
'id': state['id'],
'name': state['name'],
'code': state.get('code', '')
})
return {
'countries': countries,
'states_by_country': states_by_country,
}
@http.route(['/survey/get_country_info/<model("res.country"):country>'], type='json', auth="public",
methods=['POST'], csrf=False)
def get_country_info(self, country, **kw):
"""
Get details for a specific country including its states.
"""
if not country.exists():
return {'error': 'Country not found'}
states = []
for st in country.sudo().state_ids:
states.append({
'id': st.id,
'name': st.name,
'code': st.code or ''
})
return {
'states': states,
'phone_code': country.phone_code or '',
'zip_required': country.zip_required,
'state_required': country.state_required,
}
@http.route('/survey/download/<model("survey.user_input.line"):answer_line>/<string:answer_token>', type='http',
auth='public', website=True, csrf=False)
def survey_download_file(self, answer_line, answer_token, **kw):
"""
Securely download a file attached to a survey answer.
"""
if not answer_line.exists():
return request.not_found()
# Verify the answer token matches the user input line's token
# This ensures that only people with the correct link can download
if answer_line.user_input_id.access_token != answer_token:
return request.not_found()
if answer_line.answer_type == "ans_sh_file" and answer_line.value_ans_sh_file_fname:
try:
# Generate the secure download URL using Odoo's built-in content controller
base_url = request.httprequest.url_root.rstrip('/')
download_url = f"{base_url}/web/content/{answer_line._name}/{answer_line.id}/value_ans_sh_file/{answer_line.value_ans_sh_file_fname}?download=true&access_token={answer_token}"
return request.redirect(download_url, code=301)
except Exception:
return request.not_found()
return request.not_found()