164 lines
6.3 KiB
Python
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()
|