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:
128
encoach_api/controllers/tickets.py
Normal file
128
encoach_api/controllers/tickets.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import logging
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
from .base import EncoachMixin
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TicketsController(EncoachMixin, http.Controller):
|
||||
|
||||
# --------------------------------------------------------------- list
|
||||
@http.route('/api/tickets', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
|
||||
def list_tickets(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
domain = []
|
||||
user_type = getattr(user, 'encoach_user_type', 'student')
|
||||
if user_type not in ('admin', 'developer'):
|
||||
domain.append(('user_id', '=', user.id))
|
||||
|
||||
status = kwargs.get('status')
|
||||
if status:
|
||||
domain.append(('status', '=', status))
|
||||
|
||||
offset, limit, page = self._paginate_params(kwargs)
|
||||
Ticket = request.env['encoach.ticket'].sudo()
|
||||
total = Ticket.search_count(domain)
|
||||
records = Ticket.search(domain, offset=offset, limit=limit, order='create_date desc')
|
||||
|
||||
return self._json_response({
|
||||
'tickets': [self._serialize_ticket(t) for t in records],
|
||||
'total': total,
|
||||
'page': page,
|
||||
'limit': limit,
|
||||
})
|
||||
except Exception:
|
||||
_logger.exception("List tickets error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# -------------------------------------------------------------- create
|
||||
@http.route('/api/tickets', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
|
||||
def create_ticket(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
body = self._get_json_body()
|
||||
subject = body.get('subject', '').strip()
|
||||
if not subject:
|
||||
return self._error_response('Subject is required', 400)
|
||||
|
||||
vals = {
|
||||
'subject': subject,
|
||||
'description': body.get('description', ''),
|
||||
'user_id': user.id,
|
||||
'status': 'open',
|
||||
}
|
||||
if body.get('priority'):
|
||||
vals['priority'] = body['priority']
|
||||
if body.get('category'):
|
||||
vals['category'] = body['category']
|
||||
|
||||
ticket = request.env['encoach.ticket'].sudo().create(vals)
|
||||
return self._json_response(self._serialize_ticket(ticket), status=201)
|
||||
except Exception:
|
||||
_logger.exception("Create ticket error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# -------------------------------------------------------------- update
|
||||
@http.route(
|
||||
'/api/tickets/<int:tid>', type='http', auth='public',
|
||||
methods=['PATCH', 'OPTIONS'], csrf=False, cors='*',
|
||||
)
|
||||
def update_ticket(self, tid, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
ticket = request.env['encoach.ticket'].sudo().browse(tid)
|
||||
if not ticket.exists():
|
||||
return self._error_response('Ticket not found', 404)
|
||||
|
||||
body = self._get_json_body()
|
||||
vals = {}
|
||||
if 'subject' in body:
|
||||
vals['subject'] = body['subject']
|
||||
if 'description' in body:
|
||||
vals['description'] = body['description']
|
||||
if 'status' in body:
|
||||
vals['status'] = body['status']
|
||||
if 'priority' in body:
|
||||
vals['priority'] = body['priority']
|
||||
|
||||
if vals:
|
||||
ticket.write(vals)
|
||||
|
||||
return self._json_response(self._serialize_ticket(ticket))
|
||||
except Exception:
|
||||
_logger.exception("Update ticket error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# -------------------------------------------------------------- delete
|
||||
@http.route(
|
||||
'/api/tickets/<int:tid>', type='http', auth='public',
|
||||
methods=['DELETE', 'OPTIONS'], csrf=False, cors='*',
|
||||
)
|
||||
def delete_ticket(self, tid, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
ticket = request.env['encoach.ticket'].sudo().browse(tid)
|
||||
if not ticket.exists():
|
||||
return self._error_response('Ticket not found', 404)
|
||||
|
||||
ticket.unlink()
|
||||
return self._json_response({'ok': True})
|
||||
except Exception:
|
||||
_logger.exception("Delete ticket error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
Reference in New Issue
Block a user