from flask import session, jsonify from app.api.schemas.user_update import UserUpdateSchema # from app.models.loan import Loan from app.utils.logger import logger from app.api.services.base_service import BaseService # from app.api.schemas.eligibility_check import EligibilityCheckSchema from marshmallow import ValidationError from app.api.enums import TransactionType # from app.api.integrations import SimbrellaIntegration from app.extensions import db from app.models import Members, MembersActions, MembersProfile, Payments, MembersProducts, ProvisionActions # from app.api.services.offer_analysis import OfferAnalysis from app.api.helpers.response_helper import ResponseHelper from werkzeug.security import generate_password_hash, check_password_hash from app.api.schemas.user import UserSchema from app.api.schemas.start_profile import StartProfileSchema from app.api.schemas.profile_links import ProfileLinksSchema from flask_mail import Mail, Message import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import datetime import jwt import random from app.config import Config import smtplib, ssl from email.message import EmailMessage class AccountService(BaseService): JWT_SECRET_KEY = Config.JWT_SECRET_KEY SEND_EMAIL_FROM = Config.SEND_EMAIL_FROM SEND_EMAIL_PASS = Config.SEND_EMAIL_PASS THIS_SITE_URL = Config.THIS_SITE_URL @staticmethod def process_bar_request(data): bar_data = { "last_update": datetime.datetime.utcnow(), "top_bar": [ {"id": "1", "description": "Contacts", "last_update": "10-10-2010 11:00 AM", "value": random.randint(0, 10), "data_span": 'Last 2 months', "link": "#", "extra_style": ''}, {"id": "2", "description": "Site Traffic", "last_update": "10-10-2010 11:30 AM", "value": random.randint(0, 10), "data_span": 'Past 12 hours', "link": "#", "extra_style": ''}, {"id": "3", "description": "Appointments", "last_update": "10-12-2010 11:30 AM", "value": random.randint(0, 10), "data_span": 'Last 14 days', "link": "#", "extra_style": ''}, {"id": "4", "description": "Upgrade Account", "last_update": "10-12-2010 11:30 AM", "value": "Free Trial", "data_span": 'End: 10/10/2025', "link": "/subscription", "extra_style": " billing "} ] } return ResponseHelper.success(data=bar_data) @staticmethod def process_bar_data(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) option_name = member_data.option_name # "Free Trial" if option_name is not None and option_name != "": next_bill = f"Bill: {member_data.next_billing}" view_sub = "Account" bill_style = " next_billing " else: option_name = "Free Trial" next_bill = f"Ends: {member_data.trial_end}" view_sub = "Upgrade Account" bill_style = " billing " contacts_count = 0 # random.randint(0, 10) appointments_count = 0 site_traffic_count = 0 bar_data = { "last_update": datetime.datetime.utcnow(), "top_bar": [ {"id": "1", "description": "Contacts", "last_update": "10-10-2010 11:00 AM", "value": contacts_count, "data_span": 'Last 2 months', "link": "/contacts", "extra_style": ''}, {"id": "2", "description": "Appointments", "last_update": "10-12-2010 11:30 AM", "value": appointments_count, "data_span": 'Last 14 days', "link": "/appointments", "extra_style": ''}, {"id": "3", "description": "Site Traffic", "last_update": "10-10-2010 11:30 AM", "value": site_traffic_count, "data_span": 'Past 12 hours', "link": "/traffic", "extra_style": ''}, {"id": "4", "description": view_sub, "last_update": "10-12-2010 11:30 AM", "value": option_name, "data_span": next_bill, "link": "/subscription", "extra_style": bill_style} ] } return ResponseHelper.success(data=bar_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() def process_action_request(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) member_actions = MembersActions.get_recent_member_actions(member_data.id) member_actions_data = [] if member_actions: for t in member_actions: member_actions_data.append({ 'id': t.id, 'uid': t.uid, 'member_id': t.member_id, 'member_uid': t.member_uid, 'action_label': t.action_label, 'action_name': t.action_name, 'status_description': t.status_description, 'status': t.status, 'added': t.added, 'updated': t.updated }) action_data = { "recent_actions": member_actions_data, "last_update": datetime.datetime.utcnow(), "initial": random.randint(0, 10), "processing": random.randint(0, 10), "verifying": random.randint(0, 10), "completed": random.randint(0, 10) } # logger.info(f"Member Actions : {action_data}") return ResponseHelper.success(data=action_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_request(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member = Members.get_member_by_uid(uid) # Simulate processing response_data = { "member_id": member.id, "uid": str(uid), "username": member.username, "account_name": member.account_name, "profile_completed": member.profile_completed, "firstname": member.firstname, "lastname": member.lastname, "email": member.email, "room": member.uid, "picture": 'https://media.mermsemr.com/media/show/merms-profile', "token": user_token } return ResponseHelper.success(data=response_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_startprofile(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, StartProfileSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) practice = str(validated_data.get('practice')) specialization = str(validated_data.get('specialization')) introduction = str(validated_data.get('introduction')) url_name = str(validated_data.get('url_name')) # verify is anybody is using this url name urlNammeData = MembersProfile.get_any_member_profile_by_url_name(url_name) if urlNammeData: return { "error": 'Duplicate url name', "error_message": 'Try another url name', "url_name": url_name, }, 400 profile_uid = '' profile_completed = None member = Members.get_member_by_uid(uid) if member: # Simulate processing member_data = { "member_id": member.id, "uid": str(uid), "username": member.username, "account_name": member.account_name, "firstname": member.firstname, "lastname": member.lastname, "email": member.email, "room": member.uid, "token": user_token } current_profile = MembersProfile.get_member_profile_by_member_id(member.id) if current_profile is not None: profile_uid = current_profile.uid profile_completed = member.profile_completed else: profile_result = MembersProfile.create_member_profile(member.id, practice, specialization, introduction, url_name) if profile_result: profile_uid = profile_result.uid current_profile = MembersProfile.get_member_profile_by_member_id(member.id) if profile_uid is not None and profile_uid != '' and current_profile is not None: profile_completed = Members.set_member_profile_completed(member_data['uid']) result_data = { "profile_completed": profile_completed, "profile_uid": profile_uid, "last_update": datetime.datetime.utcnow() } return ResponseHelper.success(data=result_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_calendar(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member = Members.get_member_by_uid(uid) if not member: return { "error": 'Invalid Request', "uid": uid, }, 400 member_id = member.id dList = [] # LET get the ptovison actions prov_actions = ProvisionActions.get_provision_action_calendar_member_id(member_id=member_id, limit=100) if prov_actions: for prov_action in prov_actions: new_l = {"uid": prov_action.uid, "title": prov_action.action, "start": prov_action.added, "category": 3} dList.append(new_l) member_actions = MembersActions.get_recent_member_calendar_actions_member_id(member_id=member_id, limit=100) if member_actions: for member_action in member_actions: new_l = {"uid": member_action.uid, "title": member_action.action_label, "start": member_action.added, "category": 1} dList.append(new_l) # sample_range = random.randint(20, 60) # for x in range(sample_range): # timeMin = random.randint(1440, 2880) # calDate = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeMin * random.randint(0, 20)) # new_l = {"uid": "425611f2-c692-4404-b93d-76ca7a5ce7" + str(x), # "title": "Calendar Random Item on " + str(x), "start": calDate, # "category": random.randint(1, 4)} # dList.append(new_l) calendar_data = { "last_update": datetime.datetime.utcnow(), "category": [ { "cid": "1", "description": "Health Check" }, { "cid": "2", "description": "Product Updates" }, { "cid": "3", "description": "Provisioning" }, { "cid": "4", "description": "Contacts" } ], "list": dList } return ResponseHelper.success(data=calendar_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_payments_data(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) member_payments = Payments.get_member_payments_by_member_id(member_data.id) member_payments_data = [] for t in member_payments: member_payments_data.append({ 'id': t.id, 'uid': t.uid, 'option_name': t.option_name, 'option_type': t.option_type, 'payment_uid': t.payment_uid, 'amount': round(t.amount * 0.01, 2), 'status': t.status, 'added': t.added }) action_data = { "member_payments": member_payments_data, "last_update": datetime.datetime.utcnow(), } # logger.info(f"Member Actions : {action_data}") return ResponseHelper.success(data=action_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_profile_data(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) file_url = BaseService.get_profile_picture_url(member_data.profile_picture) personal_data = { "firstname": member_data.firstname, "lastname": member_data.lastname, "account_name": member_data.account_name, "email": member_data.email, "phone": member_data.phone, "full_address": member_data.full_address, "picture": 'https://media.mermsemr.com/media/show/merms-profile' if file_url == '' else file_url, "country": member_data.country, } external_links = { "facebook_url": "facebook.com", "twitter_url": "twitter.com", "blogger_url": "blogger.com", "google_url": "google.com", "linked_url": "linkedin.com", "website_url": "www.mysite.com", } profile_data = { "personal_data": personal_data, "external_links": external_links, } return ResponseHelper.success(data=profile_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def update_profile_data(data): try: with db.session.begin(): validated_data = AccountService.validate_data(data, UserUpdateSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) if member_data: firstname = str(validated_data.get('firstname')) lastname = str(validated_data.get('lastname')) account_name = str(validated_data.get('account_name')) phone = str(validated_data.get('phone')) full_address = str(validated_data.get('full_address')) # email = str(validated_data.get('email')) profile_data = { "firstname": firstname, "lastname": lastname, "account_name": account_name, "phone": phone, "full_address": full_address, # "email": email, } Members.set_member_update_profile(uid, profile_data) # Read the saved data member_data = Members.get_member_by_uid(uid) personal_data = { "firstname": member_data.firstname, "lastname": member_data.lastname, "account_name": member_data.account_name, "email": member_data.email, "phone": member_data.phone, "full_address": member_data.full_address, "country": member_data.country, } external_links = { "facebook_url": "facebook.com", "twitter_url": "twitter.com", "blogger_url": "blogger.com", "google_url": "google.com", "linked_url": "linkedin.com", "website_url": "www.mysite.com", } profile_data = { "personal_data": personal_data, "external_links": external_links, } return ResponseHelper.success(data=profile_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def update_profile_link_data(data): try: with db.session.begin(): url_list = data["url_list"] data.pop("url_list") validated_data = AccountService.validate_data(data, ProfileLinksSchema()) user_token = validated_data.get('token') uid = str(validated_data.get('uid')) member_data = Members.get_member_by_uid(uid) if member_data: for key in url_list.keys(): url_list_value = url_list[key] logger.info(f"URL LIST : {key} : {url_list_value}") # # firstname = str(validated_data.get('firstname')) # lastname = str(validated_data.get('lastname')) # account_name = str(validated_data.get('account_name')) # phone = str(validated_data.get('phone')) # full_address = str(validated_data.get('full_address')) # # email = str(validated_data.get('email')) # profile_data = { # "firstname": firstname, # "lastname": lastname, # "account_name": account_name, # "phone": phone, # "full_address": full_address, # # "email": email, # } # Members.set_member_update_profile(uid, profile_data) # # Read the saved data # member_data = Members.get_member_by_uid(uid) # personal_data = { # "firstname": member_data.firstname, # "lastname": member_data.lastname, # "account_name": member_data.account_name, # "email": member_data.email, # "phone": member_data.phone, # "full_address": member_data.full_address, # "country": member_data.country, # } external_links = { "facebook_url": "https://facebook.com", "twitter_url": "twitter.com", "blogger_url": "blogger.com", "google_url": "google.com", "linked_url": "linkedin.com", "website_url": "www.mysite.com", } profile_data = { "external_links": external_links, } return ResponseHelper.success(data=profile_data) except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.unprocessable_entity(result_description="Validation exception") except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") db.session.rollback() return ResponseHelper.error(result_description=str(err)) except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) db.session.rollback() return ResponseHelper.internal_server_error() @staticmethod def process_test_email(data): logger.info(f"Email Test Enter", exc_info=True) AccountService.test_new_mailer() AccountService.send_register_mail('ameye@chiefsoft.com', 'pend-uid---', 100, 'olutest', 'Ameyetest') logger.info(f"Email Test", exc_info=True) @staticmethod def test_new_mailer(): logger.info("test_new_mailer 000 ") # --- Email Configuration --- sender_email = "support@mermsemr.com" # Enter your email address receiver_email = "ameye@chiefsoft.com" # Enter the recipient's address # Use the App Password generated in Step 1 app_password = "ijcl pyko pswl phra" app_password55 = "ijclpykopswlphra" # --- Create the Email Message --- msg = EmailMessage() msg.set_content("This is the body of the email sent from Python.") msg['Subject'] = "Subject Line from Python" msg['From'] = sender_email msg['To'] = receiver_email # --- Connect to Gmail's SMTP Server and Send the Email --- smtp_server = "smtp.gmail.com" port = 465 # For SSL port = 587 # For non SSL # Create a secure SSL context # context = ssl.create_default_context() logger.info("test_new_mailer 003 ") try: logger.info("test_new_mailer 000 44") # with smtplib.SMTP_SSL(smtp_server, port, context=context) as server: with smtplib.SMTP(smtp_server, port) as server: # server.starttls() logger.info("test_new_mailer 000 55") server.login(sender_email, app_password) logger.info("test_new_mailer 000 66") server.send_message(msg) logger.info("test_new_mailer 000 77") logger.info("Email sent successfully!") # msg = EmailMessage() # msg.set_content("This is the body of the email.") # msg['Subject'] = "Test Subject" # msg['From'] = "sender@example.com" # msg['To'] = "recipient@example.com" # # server.send_message(msg) # print("Email sent successfully!") except smtplib.SMTPAuthenticationError: logger.error("Authentication error: Check your username and password.") except smtplib.SMTPConnectError as e: logger.error(f"Connection error: {e}") except smtplib.SMTPException as e: logger.error(f"An unexpected SMTP error occurred: {e}") except Exception as e: logger.error(f"An unrelated error occurred: {e}") def send_register_mail(signup_email, pending_uid, pending_id, firstname, lastname): pending_member = { "email": signup_email, "pending_uid": pending_uid, "first_name": firstname, "last_name": lastname, "pending_id": pending_id, } jwt_part = jwt.encode( {"user": pending_member, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=3330)}, AccountService.JWT_SECRET_KEY, algorithm='HS256' ) panel_url = panel_url = AccountService.THIS_SITE_URL # "https://qa-panel.mermsemr.com" link_url = str(panel_url) + '/csignup/' + jwt_part msg_body = f""" Hello {firstname}, You received this message for account verification Follow the link:{link_url} For any Support Reach Out support@mermsemr.com """ sender_email = AccountService.SEND_EMAIL_FROM sender_password = AccountService.SEND_EMAIL_PASS receiver_email = signup_email subject = "Verify your MERMS(AI) Account Setup" body = msg_body html_body = f"""\
|
| Hello {firstname}! |
|
You have received this message for your account verification |
|
Follow the link: link to complete the verification process. |