import datetime from typing import Dict, List, Optional, Set, Union from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator from app.db_sql import redis_lookup_id_random, sql_enable_part, sql_insert, sql_limit_offset_part, sql_select, sql_update from app.lib_general import log, logging, logger_reset, send_email # from app.methods.account_cfg_methods import load_account_cfg_obj # from app.methods.event_methods import load_event_obj # from app.methods.event_badge_methods import load_event_badge_obj from app.methods.event_badge_template_methods import load_event_badge_template_obj from app.models.event_badge_models import Event_Badge_Base, Event_Badge_Basic_Base # ### BEGIN ### API Event Badge Methods ### load_event_badge_obj() ### # Updated 2022-03-14 @logger_reset def load_event_badge_obj( event_badge_id: int|str, badge_only: bool = False, # Changes the SQL view used limit: int = 1000, by_alias: bool = True, exclude_unset: bool = True, model_as_dict: bool = False, enabled: str = 'enabled', # enabled, disabled, all inc_event_badge_template: bool = False, return_basic_model: bool = False, ) -> Event_Badge_Base|dict|bool: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_badge_id := redis_lookup_id_random(record_id_random=event_badge_id, table_name='event_badge'): pass else: return False if badge_only: if event_badge_rec := sql_select(table_name='v_event_badge_only', record_id=event_badge_id): pass else: return False else: if event_badge_rec := sql_select(table_name='v_event_badge', record_id=event_badge_id): pass else: return False if return_basic_model: try: event_badge_obj = Event_Badge_Basic_Base(**event_badge_rec) except ValidationError as e: log.error(e.json()) return False else: try: event_badge_obj = Event_Badge_Base(**event_badge_rec) except ValidationError as e: log.error(e.json()) return False log.debug(event_badge_obj) if return_basic_model: if event_badge_obj.pronouns_override: event_badge_obj.pronouns = event_badge_obj.pronouns_override event_badge_obj.pronouns_override = None if event_badge_obj.professional_title_override: event_badge_obj.professional_title = event_badge_obj.professional_title_override event_badge_obj.professional_title_override = None # log.debug(event_badge_obj) if event_badge_obj.full_name_override: event_badge_obj.full_name = event_badge_obj.full_name_override event_badge_obj.full_name_override = None if event_badge_obj.affiliations_override: event_badge_obj.affiliations = event_badge_obj.affiliations_override event_badge_obj.affiliations_override = None if event_badge_obj.email_override: event_badge_obj.email = event_badge_obj.email_override event_badge_obj.email_override = None if event_badge_obj.phone_override: event_badge_obj.phone = event_badge_obj.phone_override event_badge_obj.phone_override = None if event_badge_obj.location_override: event_badge_obj.location = event_badge_obj.location_override event_badge_obj.location_override = None log.debug(event_badge_obj.dict(by_alias=True, exclude_unset=True, exclude={'pronouns_override', 'professional_title_override', 'full_name_override', 'affiliations_override', 'email_override', 'phone_override', 'location_override'})) event_badge_dict = event_badge_obj.dict(by_alias=True, exclude_unset=True, exclude={'pronouns_override', 'professional_title_override', 'full_name_override', 'affiliations_override', 'email_override', 'phone_override', 'location_override'}) try: event_badge_obj = Event_Badge_Basic_Base(**event_badge_dict) except ValidationError as e: log.error(e.json()) return False log.debug(event_badge_obj) # Updated 2022-03-14 if inc_event_badge_template: log.info('Need to include event badge template data...') # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL if event_badge_template_id := event_badge_rec.get('event_badge_template_id', None): pass else: event_id = event_badge_rec.get('event_id', None) event_badge_template_id = get_event_badge_template_id_w_event_id(event_id=event_id) if event_badge_template_result := load_event_badge_template_obj( event_badge_template_id = event_badge_template_id ): log.debug(event_badge_template_result) event_badge_obj.event_badge_template = event_badge_template_result else: log.warning('A event_badge object was not returned.') event_badge_obj.event_badge_template = None if model_as_dict: return event_badge_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member else: return event_badge_obj # ### END ### API Event Badge Methods ### load_event_badge_obj() ### # ### BEGIN ### API Event Badge Methods ### get_event_badge_rec_list() ### # Updated 2022-06-14 @logger_reset def get_event_badge_rec_list( event_id: str, badge_only: bool = False, # Changes the SQL view used badge_type_code: str = None, # guest, member, non-member, staff, volunteer, custom per event printed: str = 'not_printed', # not_printed, printed, all enabled: str = 'enabled', # enabled, disabled, all limit: int = 250, offset: int = 0, ) -> list|bool: log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): pass else: return False data = {} data['event_id'] = event_id if badge_type_code: data['badge_type_code'] = badge_type_code sql_badge_type_code = f'AND `event_badge`.badge_type_code = :badge_type_code' else: sql_badge_type_code = '' if printed in ['not_printed', 'printed', 'all']: log.info(f'Creating partial SQL string for "printed" check. Printed: {printed}') if printed == 'not_printed': sql_badge_printed = f'AND (`event_badge`.print_count IS NULL OR `event_badge`.print_count = 0)' # printed = False elif printed == 'printed': sql_badge_printed = f'AND `event_badge`.print_count > 0' # printed = True elif printed == 'all': sql_badge_printed = f'AND (`event_badge`.print_count IS NULL OR `event_badge`.print_count IS NOT NULL)' # printed = None log.debug(sql_badge_printed) else: sql_badge_printed = '' sql_enabled, data['enable'] = sql_enable_part(table_name='event_badge', enabled=enabled) # Reasonably safe return str and bool sql_limit = sql_limit_offset_part(limit=limit, offset=offset) # Reasonably safe return str if badge_only: sql = f""" SELECT `event_badge`.id AS 'event_badge_id', `event_badge`.id_random AS 'event_badge_id_random' FROM `v_event_badge_only` AS `event_badge` WHERE `event_badge`.event_id = :event_id {sql_badge_type_code} {sql_badge_printed} {sql_enabled} ORDER BY event_badge.family_name ASC, event_badge.given_name ASC, `event_badge`.created_on DESC, `event_badge`.updated_on DESC {sql_limit}; """ else: sql = f""" SELECT `event_badge`.id AS 'event_badge_id', `event_badge`.id_random AS 'event_badge_id_random' FROM `v_event_badge` AS `event_badge` WHERE `event_badge`.event_id = :event_id {sql_badge_type_code} {sql_enabled} ORDER BY event_badge.family_name ASC, event_badge.given_name ASC, `event_badge`.created_on DESC, `event_badge`.updated_on DESC {sql_limit}; """ log.debug(sql) if event_badge_rec_li_result := sql_select(data=data, sql=sql, as_list=True): event_badge_rec_li = event_badge_rec_li_result else: # [] or False event_badge_rec_li = event_badge_rec_li_result log.debug(event_badge_rec_li_result) return event_badge_rec_li # ### END ### API Event Badge Methods ### get_event_badge_rec_list() ### # ### BEGIN ### API Event Badge Methods ### get_event_badge_template_id_w_event_id() ### # Updated 2021-09-14 @logger_reset def get_event_badge_template_id_w_event_id( event_id: int|str, ) -> bool|int|None: log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): pass else: return False data = {} data['event_id'] = event_id sql = f""" SELECT `event_badge_template`.id AS 'event_badge_template_id', `event_badge_template`.id_random AS 'event_badge_template_id_random', `event_badge_template`.event_id AS event_id FROM `event_badge_template` AS `event_badge_template` WHERE `event_badge_template`.event_id = :event_id LIMIT 1; """ log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL if event_badge_template_data_result := sql_select(data=data, sql=sql): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(event_badge_template_data_result) if event_badge_template_id := event_badge_template_data_result.get('event_badge_template_id', None): return event_badge_template_id else: return False else: return None # ### END ### API Event Badge Methods ### get_event_badge_template_id_w_event_id() ### # ### BEGIN ### API Event Badge Methods ### get_event_person_id_w_event_badge_id() ### # Updated 2022-04-08 @logger_reset def get_event_person_id_w_event_badge_id( event_badge_id: int|str, ) -> bool|int|None: log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_badge_id := redis_lookup_id_random(record_id_random=event_badge_id, table_name='event_badge'): pass else: return False data = {} data['event_badge_id'] = event_badge_id sql = f""" SELECT `event_badge`.id AS 'event_badge_id', `event_badge`.id_random AS 'event_badge_id_random', `event_badge`.event_person_id AS 'event_person_id' FROM `event_badge` AS `event_badge` WHERE `event_badge`.id = :event_badge_id LIMIT 1; """ log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL if event_badge_data_result := sql_select(data=data, sql=sql): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(event_badge_data_result) if event_person_id := event_badge_data_result.get('event_person_id', None): return event_person_id else: return False else: return None # ### END ### API Event Badge Methods ### get_event_badge_template_id_w_event_id() ### # ### BEGIN ### API Event Badge Methods ### create_update_event_badge_obj_v4() ### # Updated 2022-02-23 @logger_reset def create_update_event_badge_obj_v4( event_badge_dict_obj: Event_Badge_Base|dict, event_badge_id: int|str = None, # account_id: int = None, # event_id: int|str = None, event_person_id: int|str = None, create_sub_obj: bool = False, fail_any: bool = False, # Fail if any thing goes wrong for sub objects return_outline: bool = False, ) -> int|bool: log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) # ### SECTION ### Secondary data validation log.info('Checking requirements...') if event_badge_id: log.info(f'Event Badge ID passed. Update existing Event Badge. Event Badge ID: {event_badge_id}') if event_badge_id := redis_lookup_id_random(record_id_random=event_badge_id, table_name='event_badge'): pass else: log.error('Event Badge ID passed but is invalid. Failed requirement.') return False else: log.info('No Event Badge ID passed. Create new Event Badge. Required: Event Person ID') if event_person_id := redis_lookup_id_random(record_id_random=event_person_id, table_name='event_person'): pass else: log.error('Missing or invalid Event Person ID passed. Failed requirement.') log.info(f'Event Person ID: {event_person_id}') return False log.debug('Create dictionary or Pydantic object') log.debug(type(event_badge_dict_obj)) if isinstance(event_badge_dict_obj, dict): event_badge_dict = event_badge_dict_obj if event_badge_id: event_badge_dict['event_badge_id'] = event_badge_id try: event_badge_obj = Event_Badge_Base(**event_badge_dict) except ValidationError as e: log.error(e.json()) return False else: event_badge_obj = event_badge_dict_obj if event_badge_id: # NOTE: Can't update the ID alias if it was never set. event_badge_obj.id = event_badge_id log.debug(event_badge_obj) event_badge_dict = event_badge_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'event_badge_template', 'event_id', 'event_id_random', 'created_on', 'updated_on'}) # ### SECTION ### Process data if event_person_id: pass elif event_person_id := event_badge_obj.event_person_id: pass if event_badge_id: if event_badge_dict_up_result := sql_update(data=event_badge_dict, table_name='event_badge', rm_id_random=True): pass else: log.warning(f'Event Badge not updated. Event Badge ID: {event_badge_id}') log.debug(event_badge_dict_up_result) return False log.debug(event_badge_dict_up_result) else: if event_badge_dict_in_result := sql_insert(data=event_badge_dict, table_name='event_badge', rm_id_random=True, id_random_length=None): pass else: log.warning(f'Event Badge not created.') log.debug(event_badge_dict_in_result) return False log.debug(event_badge_dict_in_result) event_badge_id = event_badge_dict_in_result event_badge_outline = {} event_badge_outline['event_badge_id'] = event_badge_id if return_outline: log.debug(f'Returning the Event Badge Outline: {event_badge_outline}') return event_badge_outline else: log.debug(f'Returning the Event Badge ID: {event_badge_id}') return event_badge_id # ### END ### API Event Badge Methods ### create_update_event_badge_obj_v4() ### # ### BEGIN ### Event Badge Methods ### email_event_badge_review_url() ### # This emails the actual one time use sign in URL for a user. # Updated 2021-12-02 def email_event_badge_review_url( event_badge_id: int|str, root_url: str, ): log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) # if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass # else: return False if event_badge_id := redis_lookup_id_random(record_id_random=event_badge_id, table_name='event_badge'): pass else: return False from app.methods.event_badge_methods import load_event_badge_obj if event_badge_obj := load_event_badge_obj( event_badge_id = event_badge_id, ): log.info('Event Badge object loaded') else: return False log.debug(event_badge_obj) event_id = event_badge_obj.event_id event_badge_id_random = event_badge_obj.id_random # Not event_badge_id_random from app.methods.event_methods import load_event_obj if event_obj := load_event_obj( event_id = event_id, ): log.info('Event object loaded') else: return False log.debug(event_obj) account_id = event_obj.account_id event_name = event_obj.name from app.methods.account_cfg_methods import load_account_cfg_obj if account_cfg := load_account_cfg_obj( account_id = account_id, ): log.info('Account config loaded') else: return False log.debug(account_cfg) from_email = account_cfg.default_no_reply_email from_name = account_cfg.default_no_reply_name to_name = f'{event_badge_obj.given_name} {event_badge_obj.family_name}' to_email = event_badge_obj.email bcc_email = '' # account_cfg.confirm_email bcc_name = '' # account_cfg.confirm_name # help_tech_email = account_cfg.help_tech_email # help_tech_name = account_cfg.help_tech_name account_short_name = account_cfg.account_short_name event_badge_review_url = f'{root_url}event/badge/{event_badge_id_random}/review_badge' subject = f'{event_name}: Event Badge Review Link ({event_badge_id_random})' body_html = f"""

{to_name},

If you did not request this badge review link, please delete this email.

The link below will allow you to review your badge information and update some of the details if needed.

Click to Review Badge

Or copy and paste the link:
{event_badge_review_url}

Thank you!

""" if send_email(from_email=from_email, from_name=from_name, to_email=to_email, to_name=to_name, bcc_email=bcc_email, bcc_name=bcc_name, subject=subject, body_text=None, body_html=body_html): log.info(f'An email with a badge review link was sent to {to_email}.') return True else: log.info(f'An email with a badge review link was not sent to {to_email}.') return False # ### END ### Event Badge Methods ### email_event_badge_review_url() ###