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
This commit is contained in:
185
encoach_api/controllers/users.py
Normal file
185
encoach_api/controllers/users.py
Normal file
@@ -0,0 +1,185 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user