import json import logging from odoo import http from odoo.http import request from odoo.addons.encoach_api.controllers.base import ( jwt_required, _json_response, _error_response, _get_json_body, _paginate ) _logger = logging.getLogger(__name__) def _template_to_dict(rec): structure = None if rec.structure: try: structure = json.loads(rec.structure) except (json.JSONDecodeError, TypeError): structure = rec.structure return { 'id': rec.id, 'name': rec.name, 'code': rec.code or '', 'type': rec.type, 'editable': rec.editable, 'active': rec.active, 'subject_id': rec.subject_id.id if rec.subject_id else None, 'subject_name': rec.subject_id.name if rec.subject_id else None, 'entity_id': rec.entity_id.id if rec.entity_id else None, 'teacher_id': rec.teacher_id.id if rec.teacher_id else None, 'structure': structure, 'total_time_min': rec.total_time_min or 0, 'pass_threshold': rec.pass_threshold or 0.0, 'results_release_mode': rec.results_release_mode or 'auto', 'randomize_questions': rec.randomize_questions, 'description': rec.description or '', } class EncoachTemplatesController(http.Controller): # ------------------------------------------------------------------ # GET /api/exam/templates # ------------------------------------------------------------------ @http.route('/api/exam/templates', type='http', auth='none', methods=['GET'], csrf=False) @jwt_required def list_templates(self, **kw): try: domain = [('active', '=', True)] tpl_type = kw.get('type') if tpl_type in ('international', 'custom'): domain.append(('type', '=', tpl_type)) subject_id = kw.get('subject_id') if subject_id: domain.append(('subject_id', '=', int(subject_id))) page = int(kw.get('page', 1)) size = int(kw.get('size', 20)) Template = request.env['encoach.exam.template'].sudo() records, total = _paginate(Template, domain, page=page, size=size) return _json_response({ 'items': [_template_to_dict(r) for r in records], 'total': total, 'page': page, 'size': size, }) except Exception as e: _logger.exception('list_templates failed') return _error_response(str(e), 500) # ------------------------------------------------------------------ # GET /api/exam/templates/ # ------------------------------------------------------------------ @http.route('/api/exam/templates/', type='http', auth='none', methods=['GET'], csrf=False) @jwt_required def get_template(self, template_id, **kw): try: rec = request.env['encoach.exam.template'].sudo().browse(template_id) if not rec.exists(): return _error_response('Template not found', 404) return _json_response(_template_to_dict(rec)) except Exception as e: _logger.exception('get_template failed') return _error_response(str(e), 500) # ------------------------------------------------------------------ # POST /api/exam/templates/custom # ------------------------------------------------------------------ @http.route('/api/exam/templates/custom', type='http', auth='none', methods=['POST'], csrf=False) @jwt_required def create_custom_template(self, **kw): try: body = _get_json_body() name = body.get('name', '').strip() if not name: return _error_response('name is required', 400) structure = body.get('structure') if structure and not isinstance(structure, str): structure = json.dumps(structure) vals = { 'name': name, 'type': 'custom', 'teacher_id': request.env.user.id, 'subject_id': body.get('subject_id'), 'structure': structure, 'total_time_min': body.get('total_time_min', 0), 'pass_threshold': body.get('pass_threshold', 0.0), 'results_release_mode': body.get('results_release_mode', 'auto'), 'randomize_questions': body.get('randomize_questions', False), 'description': body.get('description', ''), } rec = request.env['encoach.exam.template'].sudo().create(vals) return _json_response(_template_to_dict(rec), 201) except Exception as e: _logger.exception('create_custom_template failed') return _error_response(str(e), 500)