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:
192
encoach_api/controllers/subscriptions.py
Normal file
192
encoach_api/controllers/subscriptions.py
Normal file
@@ -0,0 +1,192 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
from .base import EncoachMixin
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SubscriptionsController(EncoachMixin, http.Controller):
|
||||
|
||||
# ---------------------------------------------------------- packages
|
||||
@http.route('/api/packages', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False, cors='*')
|
||||
def list_packages(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
domain = [('is_active', '=', True)]
|
||||
entity_id = kwargs.get('entityID')
|
||||
if entity_id:
|
||||
domain.append(('entity_id', '=', int(entity_id)))
|
||||
|
||||
packages = request.env['encoach.package'].sudo().search(domain, order='price asc')
|
||||
return self._json_response([p.to_encoach_dict() for p in packages])
|
||||
except Exception:
|
||||
_logger.exception("List packages error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ---------------------------------------------------- stripe checkout
|
||||
@http.route('/api/stripe', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
|
||||
def create_stripe_checkout(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
body = self._get_json_body()
|
||||
package_id = body.get('packageId')
|
||||
if not package_id:
|
||||
return self._error_response('packageId is required', 400)
|
||||
|
||||
package = request.env['encoach.package'].sudo().browse(int(package_id))
|
||||
if not package.exists():
|
||||
return self._error_response('Package not found', 404)
|
||||
|
||||
success_url = body.get('successUrl', '')
|
||||
cancel_url = body.get('cancelUrl', '')
|
||||
discount_code = body.get('discountCode')
|
||||
|
||||
from odoo.addons.encoach_subscription.services.stripe_service import EncoachStripeService
|
||||
service = EncoachStripeService(request.env)
|
||||
result = service.create_checkout_session(
|
||||
user=user,
|
||||
package=package,
|
||||
success_url=success_url,
|
||||
cancel_url=cancel_url,
|
||||
discount_code=discount_code,
|
||||
)
|
||||
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("Stripe checkout error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ------------------------------------------------ paypal create order
|
||||
@http.route('/api/paypal', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
|
||||
def create_paypal_order(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
body = self._get_json_body()
|
||||
package_id = body.get('packageId')
|
||||
if not package_id:
|
||||
return self._error_response('packageId is required', 400)
|
||||
|
||||
package = request.env['encoach.package'].sudo().browse(int(package_id))
|
||||
if not package.exists():
|
||||
return self._error_response('Package not found', 404)
|
||||
|
||||
discount_code = body.get('discountCode')
|
||||
|
||||
from odoo.addons.encoach_subscription.services.paypal_service import EncoachPaypalService
|
||||
service = EncoachPaypalService(request.env)
|
||||
result = service.create_order(
|
||||
user=user,
|
||||
package=package,
|
||||
discount_code=discount_code,
|
||||
)
|
||||
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("PayPal create order error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ---------------------------------------------- paypal capture order
|
||||
@http.route('/api/paypal/approve', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
|
||||
def capture_paypal_order(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
body = self._get_json_body()
|
||||
order_id = body.get('orderId')
|
||||
if not order_id:
|
||||
return self._error_response('orderId is required', 400)
|
||||
|
||||
from odoo.addons.encoach_subscription.services.paypal_service import EncoachPaypalService
|
||||
service = EncoachPaypalService(request.env)
|
||||
result = service.capture_order(
|
||||
user=user,
|
||||
order_id=order_id,
|
||||
)
|
||||
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("PayPal capture error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ------------------------------------------------ paymob intention
|
||||
@http.route('/api/paymob', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
|
||||
def create_paymob_intention(self, **kwargs):
|
||||
try:
|
||||
user = self._authenticate()
|
||||
if not user:
|
||||
return self._error_response('Unauthorized', 401)
|
||||
|
||||
body = self._get_json_body()
|
||||
package_id = body.get('packageId')
|
||||
if not package_id:
|
||||
return self._error_response('packageId is required', 400)
|
||||
|
||||
package = request.env['encoach.package'].sudo().browse(int(package_id))
|
||||
if not package.exists():
|
||||
return self._error_response('Package not found', 404)
|
||||
|
||||
discount_code = body.get('discountCode')
|
||||
|
||||
from odoo.addons.encoach_subscription.services.paymob_service import EncoachPaymobService
|
||||
service = EncoachPaymobService(request.env)
|
||||
result = service.create_intention(
|
||||
user=user,
|
||||
package=package,
|
||||
discount_code=discount_code,
|
||||
)
|
||||
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("Paymob intention error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ------------------------------------------------ stripe webhook
|
||||
@http.route('/api/stripe/webhook', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
|
||||
def stripe_webhook(self, **kwargs):
|
||||
try:
|
||||
payload = request.httprequest.get_data(as_text=True)
|
||||
sig_header = request.httprequest.headers.get('Stripe-Signature', '')
|
||||
|
||||
from odoo.addons.encoach_subscription.services.stripe_service import EncoachStripeService
|
||||
service = EncoachStripeService(request.env)
|
||||
result = service.handle_webhook(payload, sig_header)
|
||||
|
||||
if 'error' in result:
|
||||
return self._error_response(result['error'], 400)
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("Stripe webhook error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
|
||||
# ------------------------------------------------ paymob webhook
|
||||
@http.route('/api/paymob/webhook', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
|
||||
def paymob_webhook(self, **kwargs):
|
||||
try:
|
||||
payload = request.httprequest.get_data(as_text=True)
|
||||
hmac_header = request.httprequest.args.get('hmac', '')
|
||||
|
||||
from odoo.addons.encoach_subscription.services.paymob_service import EncoachPaymobService
|
||||
service = EncoachPaymobService(request.env)
|
||||
result = service.verify_transaction(json.loads(payload), hmac_header)
|
||||
|
||||
if not result or 'error' in result:
|
||||
return self._error_response(result.get('error', 'Verification failed') if result else 'Verification failed', 400)
|
||||
return self._json_response(result)
|
||||
except Exception:
|
||||
_logger.exception("Paymob webhook error")
|
||||
return self._error_response('Internal server error', 500)
|
||||
Reference in New Issue
Block a user