# -*- coding: utf-8 -*- import random import logging from datetime import datetime, timedelta from odoo import api, fields, models _logger = logging.getLogger(__name__) class LoyaltyVerificationOtp(models.Model): _name = 'loyalty.verification.otp' _description = 'Loyalty Verification OTP' _order = 'create_date desc' email = fields.Char(string='Email') phone = fields.Char(string='Phone') otp_code = fields.Char(string='OTP Code', required=True) expiry_time = fields.Datetime(string='Expiry Time', required=True) otp_type = fields.Selection([ ('signup', 'Sign-up'), ('activation', 'Activation'), ('reset_password', 'Reset Password') ], string='OTP Type', required=True) is_verified = fields.Boolean(string='Is Verified', default=False) @api.model def generate_otp(self, email=None, phone=None, otp_type=None): if not otp_type: raise ValueError("OTP type is required.") # Generate a 6-digit random code otp_code = str(random.randint(100000, 999999)) expiry_time = fields.Datetime.now() + timedelta(minutes=15) # Create record otp_record = self.sudo().create({ 'email': email, 'phone': phone, 'otp_code': otp_code, 'expiry_time': expiry_time, 'otp_type': otp_type, }) _logger.info("Generated OTP verification code [%s] for contact %s (Type: %s)", otp_code, email or phone, otp_type) # Send Email if email: subject = "Verification Code - Mie Mapan" if otp_type == 'reset_password': subject = "Reset Password Verification Code - Mie Mapan" elif otp_type == 'activation': subject = "Account Activation Verification Code - Mie Mapan" body_html = f"""
Mie Mapan

Hi,

Thank you for choosing Mie Mapan. Use the following OTP to complete your request. This OTP is valid for 15 minutes.

{otp_code}

Regards,
Mie Mapan Team


Mie Mapan Inc

""" mail_values = { 'subject': subject, 'body_html': body_html, 'email_to': email, 'email_from': self.env.user.email or 'no-reply@miemapan.com', } # Send using sudo context self.env['mail.mail'].sudo().create(mail_values).send() return otp_record @api.model def verify_otp(self, otp_code, email=None, phone=None, otp_type=None): if not otp_code: return False domain = [ ('otp_code', '=', otp_code), ('otp_type', '=', otp_type), ('is_verified', '=', False), ('expiry_time', '>=', fields.Datetime.now()) ] if email: domain.append(('email', '=', email)) if phone: domain.append(('phone', '=', phone)) record = self.sudo().search(domain, order='create_date desc', limit=1) if record: record.write({'is_verified': True}) return True return False