# 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/'], 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//', 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()