Files
full_encoach_platform/odoo/addons/rpc/controllers/json2.py
Yamen Ahmad 3e83d8d7d5 feat: add complete EnCoach backend — Odoo 19 + all addons
Includes:
- Odoo 19 framework (odoo/)
- 27 custom EnCoach addons (new_project/custom_addons/)
  - encoach_core, encoach_api, encoach_lms_api, encoach_adaptive_api
  - encoach_exam, encoach_taxonomy, encoach_adaptive, encoach_assignment
  - encoach_ai, encoach_ai_grading, encoach_ai_generation, encoach_ai_media
  - encoach_courseware, encoach_communication, encoach_subscription
  - encoach_notification, encoach_approval, encoach_branding
  - encoach_classroom, encoach_registration, encoach_stats
  - encoach_faq, encoach_ticket, encoach_training, encoach_resources
  - encoach_adaptive_ai, encoach_sis
- 21 OpenEduCat Enterprise modules (new_project/enterprise-19/)
- 14 OpenEduCat Community modules (new_project/openeducat_erp-19.0/)
- Configuration: odoo.conf, requirements.txt, scripts
- 200+ REST API endpoints with JWT authentication
- SRS and test documentation

Made-with: Cursor
2026-04-01 17:10:04 +04:00

91 lines
2.6 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import inspect
import logging
from collections.abc import Mapping, Sequence
from typing import Any
from werkzeug.exceptions import (
NotFound,
UnprocessableEntity,
)
from odoo import http
from odoo.http import request
from odoo.models import BaseModel
from odoo.service.model import get_public_method
from odoo.tools import frozendict
_logger = logging.getLogger(__name__)
class WebJson2Controller(http.Controller):
def _web_json_2_rpc_readonly(self, rule, args):
try:
model_name = args['__model__']
method_name = args['__method__']
Model = request.registry[model_name]
except KeyError:
# no need of a read/write cursor to send a 404 http error
return True
for cls in Model.mro():
method = getattr(cls, method_name, None)
if method is not None and hasattr(method, '_readonly'):
return method._readonly
return False
# Take over /json/<path:subpath>
@http.route(
['/json/2', '/json/2/<path:subpath>'],
auth='public',
type='json2',
readonly=True,
methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
)
def web_json_2_404(self, subpath=None):
e = "Did you mean POST /json/2/<model>/<method>?"
raise request.not_found(e)
@http.route(
'/json/2/<__model__>/<__method__>',
methods=['POST'],
auth='bearer',
type='json2',
readonly=_web_json_2_rpc_readonly,
save_session=False,
)
def web_json_2_rpc(
self,
__model__: str,
__method__: str,
ids: Sequence[int] = (),
context: Mapping[str, Any] = frozendict(),
**kwargs,
):
try:
Model = request.env[__model__].with_context(context)
except KeyError as exc:
e = f"the model {__model__!r} does not exist"
raise NotFound(e) from exc
try:
func = get_public_method(Model, __method__)
except AttributeError as exc:
raise NotFound(exc.args[0]) from exc
if hasattr(func, '_api_model') and ids:
e = f"cannot call {__model__}.{__method__} with ids"
raise UnprocessableEntity(e)
records = Model.browse(ids)
signature = inspect.signature(func)
try:
signature.bind(records, **kwargs)
except TypeError as exc:
raise UnprocessableEntity(exc.args[0])
result = func(records, **kwargs)
if isinstance(result, BaseModel):
result = result.ids
return result