Files
encoach_be_odoo19/encoach_api/controllers/users.py
Talal Sharabi f5b627256f EnCoach Odoo 19 custom modules
Full backend implementation with custom Odoo modules:
- encoach_api: Core API, user management, JWT auth
- encoach_exam: Exam generation (reading, writing, listening, speaking)
- encoach_evaluate: AI-powered evaluation (writing, speaking)
- encoach_training: Training tips and walkthrough
- encoach_storage: File storage management
- encoach_payment: Stripe, PayPal, Paymob integration
- encoach_mail: Email notifications

Made-with: Cursor
2026-03-14 16:46:46 +04:00

186 lines
7.4 KiB
Python

import logging
from odoo import http
from odoo.http import request
from .base import EncoachMixin
_logger = logging.getLogger(__name__)
class UsersController(EncoachMixin, http.Controller):
# ---------------------------------------------------------- current user
@http.route('/api/user', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
def get_current_user(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
return self._json_response(self._serialize(user))
except Exception:
_logger.exception("Get current user error")
return self._error_response('Internal server error', 500)
# ----------------------------------------------------------- update user
@http.route(
'/api/users/update', type='http', auth='public',
methods=['POST', 'PATCH', 'OPTIONS'], csrf=False, cors='*',
)
def update_user(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
body = self._get_json_body()
vals = {}
field_map = {
'name': 'name',
'phone': 'phone',
'nativeLanguage': 'encoach_native_language',
'country': 'encoach_country',
'learningGoal': 'encoach_learning_goal',
'image': 'encoach_image_url',
}
for api_field, odoo_field in field_map.items():
if api_field in body:
vals[odoo_field] = body[api_field]
if 'password' in body and body['password']:
vals['password'] = body['password']
if vals:
user.sudo().write(vals)
updated = request.env['res.users'].sudo().browse(user.id)
return self._json_response(self._serialize(updated))
except Exception:
_logger.exception("Update user error")
return self._error_response('Internal server error', 500)
# ------------------------------------------------------------- list users
@http.route('/api/users/list', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
def list_users(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
offset, limit, page = self._paginate_params(kwargs)
domain = []
search = kwargs.get('search', '').strip()
if search:
domain.append('|')
domain.append(('name', 'ilike', search))
domain.append(('login', 'ilike', search))
user_type = kwargs.get('type')
if user_type:
domain.append(('encoach_user_type', '=', user_type))
entity_id = kwargs.get('entityID')
if entity_id:
domain.append(('encoach_entity_id', '=', int(entity_id)))
Users = request.env['res.users'].sudo()
total = Users.search_count(domain)
records = Users.search(domain, offset=offset, limit=limit, order='name asc')
return self._json_response({
'users': [self._serialize(u) for u in records],
'total': total,
'page': page,
'limit': limit,
})
except Exception:
_logger.exception("List users error")
return self._error_response('Internal server error', 500)
# ---------------------------------------------------------- get user by id
@http.route('/api/users/<int:user_id>', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
def get_user(self, user_id, **kwargs):
try:
auth_user = self._authenticate()
if not auth_user:
return self._error_response('Unauthorized', 401)
target = request.env['res.users'].sudo().browse(user_id)
if not target.exists():
return self._error_response('User not found', 404)
return self._json_response(self._serialize(target))
except Exception:
_logger.exception("Get user error")
return self._error_response('Internal server error', 500)
# --------------------------------------------------- user controller action
@http.route('/api/users/controller', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
def user_controller(self, **kwargs):
"""Handle user controller actions such as transferring users between groups."""
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
body = self._get_json_body()
action = body.get('action')
if not action:
return self._error_response('Action is required', 400)
Group = request.env['encoach.group'].sudo()
if action == 'transfer':
user_ids = body.get('userIds', [])
from_group_id = body.get('fromGroupId')
to_group_id = body.get('toGroupId')
if not user_ids or not to_group_id:
return self._error_response('userIds and toGroupId are required', 400)
if from_group_id:
from_group = Group.browse(int(from_group_id))
if from_group.exists():
from_group.write({
'participant_ids': [(3, int(uid)) for uid in user_ids],
})
to_group = Group.browse(int(to_group_id))
if not to_group.exists():
return self._error_response('Target group not found', 404)
to_group.write({
'participant_ids': [(4, int(uid)) for uid in user_ids],
})
return self._json_response({'ok': True})
if action == 'remove':
user_ids = body.get('userIds', [])
group_id = body.get('groupId')
if not user_ids or not group_id:
return self._error_response('userIds and groupId are required', 400)
group = Group.browse(int(group_id))
if group.exists():
group.write({
'participant_ids': [(3, int(uid)) for uid in user_ids],
})
return self._json_response({'ok': True})
return self._error_response(f'Unknown action: {action}', 400)
except Exception:
_logger.exception("User controller error")
return self._error_response('Internal server error', 500)
# ---------------------------------------------------------- user balance
@http.route('/api/users/balance', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
def user_balance(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
balance = getattr(user, 'encoach_balance', 0)
return self._json_response({'balance': balance})
except Exception:
_logger.exception("User balance error")
return self._error_response('Internal server error', 500)