From 0eaaaa4d7e8234b08963c27a5362d1d55845ef85 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Thu, 12 Jan 2023 18:21:00 -0500 Subject: [PATCH] Changes related to Docker, bug fixes, and event badges. --- app/main.py | 7 +- app/models/event_badge_models.py | 34 +- app/models/event_exhibit_tracking_models.py | 10 +- app/models/event_person_models.py | 11 +- app/models/event_person_profile_models.py | 3 +- app/models/event_person_tracking_models.py | 2 +- app/routers/event_badge_importing.py | 474 ++++++++++++++++++++ app/routers/event_exhibit_tracking.py | 24 +- app/routers/event_person.py | 4 +- app/routers/event_reports.py | 2 +- 10 files changed, 530 insertions(+), 41 deletions(-) create mode 100644 app/routers/event_badge_importing.py diff --git a/app/main.py b/app/main.py index c501414..5851e40 100644 --- a/app/main.py +++ b/app/main.py @@ -18,7 +18,7 @@ from . import config from app.log import log, logging # Import the routers here first: -from app.routers import aether_cfg, api_crud, api, importing, sql, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, data_store, event, event_badge, event_badge_template, event_device, event_exhibit, event_exhibit_tracking, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, fundraising, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, qr, site, site_domain, user, websockets, e_cvent, c_idaa, e_impexium, e_stripe +from app.routers import aether_cfg, api_crud, api, importing, sql, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, data_store, event, event_badge, event_badge_importing, event_badge_template, event_device, event_exhibit, event_exhibit_tracking, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, fundraising, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, qr, site, site_domain, user, websockets, e_cvent, c_idaa, e_impexium, e_stripe from app.db_sql import sql_select # , sql_connect @@ -176,9 +176,12 @@ app.include_router( ) app.include_router( event_badge.router, - # prefix='/event/badge', tags=['Event Badge'], ) +app.include_router( + event_badge_importing.router, + tags=['Event Badge Importing'], +) app.include_router( event_badge_template.router, # prefix='/event/badge/template', diff --git a/app/models/event_badge_models.py b/app/models/event_badge_models.py index 32315b0..5277a50 100644 --- a/app/models/event_badge_models.py +++ b/app/models/event_badge_models.py @@ -40,8 +40,11 @@ class Event_Badge_Base(BaseModel): person_id: Optional[int] external_id: Optional[str] # Generated internally or externally. Needs to be stable. It should not change. - external_sys_id: Optional[str] # Person ID generated by external system (should be stable and not change) - external_reg_id: Optional[str] # Registration ID generated by external system (should be stable and not change) + external_event_id: Optional[str] # Event ID generated by external system. Needs to be stable. It should not change. + external_registration_id: Optional[str] # Registration ID generated by external system (should be stable and not change) + external_reg_id: Optional[str] # NOTE: Deprecated; Move to external_registration_id. Registration ID generated by external system (should be stable and not change) + external_person_id: Optional[str] # Person ID generated by external system (should be stable and not change) + external_sys_id: Optional[str] # NOTE: Deprecated; Move to external_person_id. Person ID generated by external system (should be stable and not change) pronouns: Optional[str] # Preferred pronouns informal_name: Optional[str] @@ -52,28 +55,32 @@ class Event_Badge_Base(BaseModel): family_name: Optional[str] designations: Optional[str] # Temporary or long-term designations related to family, relationships, person differentiation (Junior/Senior), location, social status, professional qualifications, legal status, or other name suffix - degree: Optional[str] # NOTE: Phasing out! Use *designations* instead. - degrees: Optional[str] # NOTE: Phasing out! Use *designations* instead. - credentials: Optional[str] # NOTE: Phasing out! Use *designations* instead. + # degree: Optional[str] # NOTE: Phasing out! Use *designations* instead. + # degrees: Optional[str] # NOTE: Phasing out! Use *designations* instead. + # credentials: Optional[str] # NOTE: Phasing out! Use *designations* instead. professional_title: Optional[str] # Professional title - display_professional_title: Optional[str] # Override professional title - title: Optional[str] # NOTE: Phasing out! Use *professional_title* instead. + display_professional_title: Optional[str] # NOTE: Deprecated! Phasing out! Use *full_name_override* instead. + professional_title_override: Optional[str] # Override professional title + # title: Optional[str] # NOTE: Phasing out! Use *professional_title* instead. - display_name: Optional[str] # # Override full_name; Actual name shown on badge and other "public" areas + display_name: Optional[str] # NOTE: Deprecated! Phasing out! Use *full_name_override* instead. + full_name_override: Optional[str] # # Override full_name; Actual name shown on badge and other "public" areas # BEGIN # Auto created name variations full_name: Optional[str] # title_names given_name middle_name family_name designations affiliations: Optional[str] # One or more affiliations with organizations, companies, and other groups - affiliation: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. - affiliation_name: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. - display_affiliations: Optional[str] # Override affiliations + # affiliation: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. + # affiliation_name: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. + display_affiliations: Optional[str] # NOTE: Deprecated! Phasing out! Use *affiliations_override* instead. + affiliations_override: Optional[str] # Override affiliations email: Optional[str] phone: Optional[str] - display_phone: Optional[str] + display_phone: Optional[str] # NOTE: Deprecated! Phasing out! Use *phone_override* instead. + phone_override: Optional[str] address_line_1: Optional[str] address_line_2: Optional[str] @@ -97,7 +104,8 @@ class Event_Badge_Base(BaseModel): location: Optional[str] # Actual location name shown on badge and other "public" areas location_short: Optional[str] # Auto generated short version location_long: Optional[str] # Auto generated long version - display_location: Optional[str] # Override location + display_location: Optional[str] # NOTE: Deprecated! Phasing out! Use *location_override* instead. + location_override: Optional[str] # Override location # This is updated using SQL triggers and a SQL function # Combines informal, given, middle, family, email diff --git a/app/models/event_exhibit_tracking_models.py b/app/models/event_exhibit_tracking_models.py index 8fbde6c..d2b583c 100644 --- a/app/models/event_exhibit_tracking_models.py +++ b/app/models/event_exhibit_tracking_models.py @@ -58,14 +58,14 @@ class Event_Exhibit_Tracking_Base(BaseModel): event_badge_given_name: Optional[str] event_badge_middle_name: Optional[str] event_badge_family_name: Optional[str] - event_badge_display_name: Optional[str] event_badge_full_name: Optional[str] + event_badge_full_name_override: Optional[str] event_badge_designations: Optional[str] event_badge_professional_title: Optional[str] - event_badge_display_professional_title: Optional[str] + event_badge_professional_title_override: Optional[str] event_badge_affiliations: Optional[str] - event_badge_display_affiliations: Optional[str] + event_badge_affiliations_override: Optional[str] event_badge_email: Optional[str] @@ -85,13 +85,13 @@ class Event_Exhibit_Tracking_Base(BaseModel): event_badge_country: Optional[str] # event_badge_location: Optional[str] - event_badge_display_location: Optional[str] + event_badge_location_override: Optional[str] event_person_informal_name: Optional[str] event_person_given_name: Optional[str] event_person_family_name: Optional[str] - event_person_display_name: Optional[str] event_person_full_name: Optional[str] + event_person_full_name_override: Optional[str] event_person_affiliations: Optional[str] event_person_email: Optional[str] diff --git a/app/models/event_person_models.py b/app/models/event_person_models.py index 21b38f5..0dc5f0e 100644 --- a/app/models/event_person_models.py +++ b/app/models/event_person_models.py @@ -57,8 +57,11 @@ class Event_Person_Base(BaseModel): user_id: Optional[int] external_id: Optional[str] # Generated internally or externally. Needs to be stable. It should not change. - external_sys_id: Optional[str] # Person ID generated by external system (should be stable and not change) - external_reg_id: Optional[str] # Registration ID generated by external system (should be stable and not change) + external_event_id: Optional[str] # Event ID generated by external system. Needs to be stable. It should not change. + external_registration_id: Optional[str] # Registration ID generated by external system (should be stable and not change) + external_reg_id: Optional[str] # NOTE: Deprecated; Move to external_registration_id. Registration ID generated by external system (should be stable and not change) + external_person_id: Optional[str] # Person ID generated by external system (should be stable and not change) + external_sys_id: Optional[str] # NOTE: Deprecated; Move to external_person_id. Person ID generated by external system (should be stable and not change) file_count: Optional[int] @@ -76,8 +79,8 @@ class Event_Person_Base(BaseModel): event_badge_informal_name: Optional[str] event_badge_given_name: Optional[str] event_badge_family_name: Optional[str] - event_badge_display_name: Optional[str] event_badge_full_name: Optional[str] + event_badge_full_name_override: Optional[str] event_badge_affiliations: Optional[str] event_badge_email: Optional[str] event_badge_city: Optional[str] @@ -88,7 +91,7 @@ class Event_Person_Base(BaseModel): event_person_informal_name: Optional[str] event_person_given_name: Optional[str] event_person_family_name: Optional[str] - event_person_display_name: Optional[str] + event_person_name_override: Optional[str] event_person_full_name: Optional[str] event_person_affiliations: Optional[str] event_person_email: Optional[str] diff --git a/app/models/event_person_profile_models.py b/app/models/event_person_profile_models.py index 58bead8..5fb160f 100644 --- a/app/models/event_person_profile_models.py +++ b/app/models/event_person_profile_models.py @@ -51,7 +51,8 @@ class Event_Person_Profile_Base(BaseModel): professional_title: Optional[str] # Professional title - display_name: Optional[str] # Actual name shown in the directory and other "public" areas + display_name: Optional[str] # View of display_override. Actual name shown in the directory and other "public" areas + full_name_override: Optional[str] # Actual name shown in the directory and other "public" areas # BEGIN # Auto created name variations full_name: Optional[str] # title_names given_name middle_name family_name designations diff --git a/app/models/event_person_tracking_models.py b/app/models/event_person_tracking_models.py index 2b23a55..28219f7 100644 --- a/app/models/event_person_tracking_models.py +++ b/app/models/event_person_tracking_models.py @@ -71,8 +71,8 @@ class Event_Person_Tracking_Base(BaseModel): event_person_informal_name: Optional[str] event_person_given_name: Optional[str] event_person_family_name: Optional[str] - event_person_display_name: Optional[str] event_person_full_name: Optional[str] + event_person_full_name_override: Optional[str] event_person_affiliations: Optional[str] event_person_email: Optional[str] event_session_name: Optional[str] diff --git a/app/routers/event_badge_importing.py b/app/routers/event_badge_importing.py new file mode 100644 index 0000000..f7db996 --- /dev/null +++ b/app/routers/event_badge_importing.py @@ -0,0 +1,474 @@ +import datetime, json, os, pathlib, pytz, secrets, shutil, time +import pandas, xlrd # qrcode +from fastapi import APIRouter, Body, Depends, File, Header, HTTPException, Query, Response, status, UploadFile +from pydantic import BaseModel, EmailStr, Field +from typing import Dict, List, Optional, Set, Union + +from app.lib_general import log, logging, secure_hash_string, common_route_params, Common_Route_Params +from app.config import settings +from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, sql_delete, redis_lookup_id_random + +from app.routers.api_crud import delete_obj_template, get_obj_template, get_obj_li_template, patch_obj_template, post_obj_template + +from app.methods.event_person_methods import create_event_person_obj, create_update_event_person_obj_v4, get_event_person_rec_list, load_event_person_obj, update_event_person_obj, update_event_person_obj_v3 +# from app.methods.event_session_methods import create_update_event_session_obj_v4, get_event_session_rec_list, load_event_session_obj, update_event_session_obj +# from app.methods.event_presentation_methods import create_update_event_presentation_obj_v4, get_event_presentation_rec_list, load_event_presentation_obj +# from app.methods.event_presenter_methods import create_update_event_presenter_obj_v4, get_event_presenter_rec_list, load_event_presenter_obj +from app.methods.hosted_file_methods import load_hosted_file_obj, save_file + +from app.models.event_models import Event_Base +# from app.models.event_location_models import Event_Location_Base +from app.models.event_person_models import Event_Person_Base +# from app.models.event_presentation_models import Event_Presentation_Base +# from app.models.event_presenter_models import Event_Presenter_Base +# from app.models.event_session_models import Event_Session_Base + +from app.models.response_models import Resp_Body_Base, mk_resp + + +router = APIRouter() + + +# Based on the program import template the clients are given. +# Ideally the import file should only contain records with new External IDs. Old records will be checked and only updated if needed. +# Updated 2021-10-19 + + +# ### BEGIN ### Event Importing ### event_importing_program_data() ### +# Based on the program import template the clients are given. +# Create and update locations, sessions, presentations, and presenters as needed. +# Updated 2023-01-12 +@router.post('/event/{event_id}/badge/import', response_model=Resp_Body_Base) +async def event_id_badge_import( + event_id: str = Query(..., min_length=11, max_length=22), + file: UploadFile = File(...), + + begin_at: int = 0, + end_at: int = 20000, + + return_detail: bool = False, + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + allow_inserts = True + allow_updates = True + + account_id = commons.x_account_id + # event_location_id = None + # event_session_id = None + # event_presentation_id = None + # event_presenter_id = None + + # Processing Config Options: + # How should the external_id generation and matching be done? + # external_sys_id, external_reg_id and given and family name + # prefix external_id with related events (registration setups) from external system + # external_id from: external_sys_id, external_reg_id + + event_id_random = event_id + if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): pass + else: return mk_resp(data=None, status_code=404, response=commons.response) + + link_to_type = 'event' + link_to_id = event_id + + file_info = await save_file( + file = file, + account_id = account_id, + # account_id_random = account_id_random, + link_to_type = link_to_type, + link_to_id = link_to_id, + # link_to_id_random = link_to_id_random, + # check_allowed_extension = check_allowed_extension, + ) + if file_info['saved']: + log.info('File saved') + log.debug(file_info) + else: + log.error('Something may have gone wrong while saving the uploaded file?') + return mk_resp(data=None, status_code=500, response=commons.response) + + # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + + hosted_files_path = settings.FILES_PATH['hosted_files_root'] + # hosted_files_path = '/home/scott/tmp/hosted_files_dev/' + log.info(f'Hosted Files Path: {hosted_files_path}') + log.debug(shutil.disk_usage(hosted_files_path)) + + # full_file_path = 'admin/temp/import_event_program_external_id.csv' + subdirectory_dest = os.path.join(hosted_files_path, file_info.get('subdirectory_path')) + log.debug(subdirectory_dest) + hash_filename = file_info.get('hash_sha256')+'.file' + full_file_path = pathlib.Path( os.path.join(subdirectory_dest, hash_filename) ) # NOTE: Must use pathlib.Path to use .exists() + log.debug(full_file_path) + + if full_file_path.exists(): + log.info(f'Full File Path: {full_file_path}') + else: + log.warning(f'Not found at full File Path: {full_file_path}') + return mk_resp(data=None, status_code=500, response=commons.response) + + # return mk_resp(data=file_info, response=commons.response) + + df = pandas.read_csv( + full_file_path, + na_filter=False, + dtype={ + 'external_id': str, 'External ID': str, # Must be unique per person; Generate if needed + 'external_event_id': str, 'External Event ID': str, # Usually same for all registrants + 'external_registration_id': str, 'External Registration ID': str, # Must be unique per registration (may be more than one person; usually guests) + 'external_person_id': str, 'External Person ID': str, # Must be unique per person + # 'external_sys_id': str, 'External Sys ID': str, # Must be unique per person + + 'event_badge_template_id': int, 'Event Badge Template ID': int, # An actual ID number + + # 'event_location_external_id': str, 'event_location_code': str, 'event_location_sort': int, + # 'event_presentation_external_id': str, 'event_presentation_code': str, 'event_presentation_sort': int, + # 'event_presenter_external_id': str, 'event_presenter_code': str, 'event_presenter_number': int, 'event_presenter_designations': str, 'event_presenter_sort': int, + # 'event_session_external_id': str, 'event_session_code': str, 'event_session_sort': int, + + # 'location_external_id': str, 'location_code': str, 'location_sort': int, + # 'presentation_external_id': str, 'presentation_code': str, 'presentation_sort': int, + # 'presenter_external_id': str, 'presenter_code': str, 'presenter_number': int, 'presenter_designations': str, 'presenter_sort': int, + # 'session_external_id': str, 'session_code': str, 'session_sort': int, + + # 'source_id': str, 'Source ID': str, + + 'pronouns': str, 'Pronouns': str, # For badge rendering + 'informal_name': str, 'Informal Name': str, # For badge rendering + 'title_names': str, 'Title Names': str, # For badge rendering + 'given_name': str, 'Given Name': str, # For badge rendering + 'middle_name': str, 'Middle Name': str, # For badge rendering + 'family_name': str, 'Family Name': str, # For badge rendering + 'designations': str, 'Designations': str, # For badge rendering + 'professional_title': str, 'Professional Title': str, # For badge rendering + 'professional_title_override': str, 'display_professional_title': str, 'Display Professional Title': str, # For badge rendering override + + 'full_name': str, 'Full Name': str, + 'full_name_override': str, 'display_name': str, 'Display Name': str, 'Full Name Override': str, # For badge rendering override + + 'affiliations': str, 'Affiliations': str, # For badge rendering override + 'affiliations_override': str, 'display_affiliations': str, 'Display Affiliations': str, # For badge rendering override + + 'email': str, 'Email Address': str, + + 'phone': str, 'Phone': str, + 'address_line_1': str, 'Address Line 1': str, + 'address_line_2': str, 'Address Line 2': str, + 'address_line_3': str, 'Address Line 3': str, + 'city': str, 'City': str, + 'country_subdivision_code': str, 'Country Subdivision Code': str, + 'state_province': str, 'State Province': str, + 'state_province_abb': str, 'State Province Abb': str, + 'postal_code': str, 'Postal Code': str, + 'country_alpha_2_code': str, 'Country Alpha 2 Code': str, + 'country': str, 'Country': str, + 'full_address': str, 'Full Address': str, + + 'location': str, 'Location': str, # For badge rendering + 'location_override': str, 'display_location': str, 'Display Location': str, # For badge rendering override + + 'badge_type_code': str, 'Badge Type Code': str, # Must be mapped to a badge template ID + 'badge_type_code_override': str, 'Badge Type Code Override': str, + 'badge_type': str, 'Badge Type': str, + 'badge_type_override': str, 'Badge Type Override': str, + + 'member_type_code': str, 'Member Type Code': str, + 'member_type': str, 'Member Type': str, + + 'registration_type_code': str, 'Registration Type Code': str, + 'registration_type': str, 'Registration Type': str, + + 'other_1': str, 'Other 1': str, + 'other_2': str, 'Other 2': str, + + 'ticket_1_code': str, 'Ticket 1 Code': str, + 'ticket_2_code': str, 'Ticket 2 Code': str, + 'ticket_3_code': str, 'Ticket 3 Code': str, + 'ticket_4_code': str, 'Ticket 4 Code': str, + 'ticket_5_code': str, 'Ticket 5 Code': str, + 'ticket_6_code': str, 'Ticket 6 Code': str, + 'ticket_7_code': str, 'Ticket 7 Code': str, + 'ticket_8_code': str, 'Ticket 8 Code': str, + + 'allow_tracking': str, 'Allow Tracking': str, + 'agree_to_tc': str, 'Agree to TC': str, + } + ) + df.rename(columns={ + 'External ID': 'external_id', + 'External Event ID': 'external_event_id', + 'External Registration ID': 'external_registration_id', + 'External Person ID': 'external_person_id', + 'External Sys ID': 'external_person_id', + + 'Event Badge Template ID': 'event_badge_template_id', + + 'Pronouns': 'pronouns', + 'Informal_name': 'informal_name', + 'Title Names': 'title_names', + 'Given Name': 'given_name', + 'Middle Name': 'middle_name', + 'Family Name': 'family_name', + 'Designations': 'designations', + 'Professional Title': 'professional_title', + + 'Full Name': 'full_name', + 'Display Name': 'full_name_override', + 'Full Name Override': 'full_name_override', + + 'Affiliations': 'affiliations', + + # 'Title': 'presenter_title_names', + # 'Prefix': 'presenter_title_names', + # 'Nickname': 'presenter_informal_name', + # 'given_name (first)': 'presenter_given_name', + # 'First Name': 'presenter_given_name', + # 'family_name (last)': 'presenter_family_name', + # 'Last Name': 'presenter_family_name', + # 'Suffix': 'presenter_designations', + + 'Email': 'email', + 'Email Address': 'email', + 'CC Email Address': 'cc_email', + + 'Phone': 'phone', + + 'Location': 'location', + + 'Badge Type Code': 'badge_type_code', + 'Badge Type': 'badge_type', + + 'Member Type Code': 'member_type_code', + 'Member Type': 'member_type', + + 'Registration Type Code': 'registration_type_code', + 'Registration Type': 'registration_type', + + 'Other 1': 'other_1', + 'Other 2': 'other_2', + + 'Ticket 1 Code': 'ticket_1_code', + 'Ticket 2 Code': 'ticket_2_code', + 'Ticket 3 Code': 'ticket_3_code', + 'Ticket 4 Code': 'ticket_4_code', + 'Ticket 5 Code': 'ticket_5_code', + 'Ticket 6 Code': 'ticket_6_code', + 'Ticket 7 Code': 'ticket_7_code', + 'Ticket 8 Code': 'ticket_8_code', + + 'Allow Tracking': 'allow_tracking', + 'Agree to TC': 'agree_to_tc', + + # 'location_title': 'location_name', + # 'Location Code': 'location_code', + # 'Location Name': 'location_name', + # 'session_location': 'location_name', + # 'Session Location': 'location_name', + + # 'session_title': 'session_name', + # 'Session Code': 'session_code', + # 'Session Name': 'session_name', + + # 'presentation_title': 'presentation_name', + # 'Presentation Code': 'presentation_code', + # 'Presentation Name': 'presentation_name', + + # 'Presenter Code': 'code', + # 'Presenter Number': 'number', # for sorting + # 'Presenter Name': 'name', + }, + inplace = True) + # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(df) + + df_dict = df.to_dict(orient='records') + + log.info(f'Total record count: {len(df_dict)}') + + loop_count = 0 + event_badge_person_li = [] + event_badge_person_summary_li = [] + + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + for record in df_dict: + # ### Figure out the external IDs + log.info(f'Loop Count: {loop_count}') + loop_count = loop_count + 1 + if loop_count <= begin_at: continue + if loop_count > end_at: break + + + if external_id := record.get('external_id'): + log.info('Using given external_id for external_id') + elif record.get('external_registration_id') and record.get('external_person_id'): + log.info('Using external_registration_id and external_person_id for external_id') + external_id = str(record.get('external_registration_id'))+':'+str(record.get('external_person_id')) + elif record.get('external_event_id') and record.get('external_person_id'): + log.info('Using external_event_id and external_person_id for external_id') + external_id = str(record.get('external_event_id'))+':'+str(record.get('external_person_id')) + elif record.get('external_person_id'): + log.info('Using only external_person_id for external_id') + external_id = str(record.get('external_person_id')) + elif record.get('external_registration_id'): + log.info('Using only external_registration_id for external_id') + external_id = str(record.get('external_registration_id')) + else: + log.warning('No external ID was found or could safely be generated.') + break + log.debug(f'Event Badge External ID: {external_id}') + + event_person_summary = {} + event_person_summary['event_id'] = event_id + event_person_summary['event_id_random'] = event_id_random + event_person_summary['external_id'] = external_id + event_person_summary['given_name'] = record.get('given_name') + event_person_summary['family_name'] = record.get('family_name') + event_person_summary['email'] = record.get('email') + + event_person_data = {} + event_person_data['account_id'] = account_id # Is this needed? + event_person_data['event_id'] = event_id + event_person_data['enable'] = True + event_person_data['external_id'] = external_id + event_person_data['external_event_id'] = record.get('external_event_id') + event_person_data['external_registration_id'] = record.get('external_registration_id') + # event_person_data['external_reg_id'] = record.get('external_registration_id') # Deprecated + event_person_data['external_person_id'] = record.get('external_person_id') + # event_person_data['external_sys_id'] = record.get('external_person_id') # Deprecated + + event_person_data['event_badge'] = {} + event_person_data['event_person_profile'] = {} + # event_person_data['event_registration'] = {} # Not currently used + + event_person_data['event_person_profile']['enable'] = True + + event_person_data['event_person_profile']['pronouns'] = record.get('pronouns') + event_person_data['event_person_profile']['informal_name'] = record.get('informal_name') + event_person_data['event_person_profile']['title_names'] = record.get('title_names') + event_person_data['event_person_profile']['given_name'] = record.get('given_name') + event_person_data['event_person_profile']['family_name'] = record.get('family_name') + event_person_data['event_person_profile']['designations'] = record.get('designations') + event_person_data['event_person_profile']['professional_title'] = record.get('professional_title') + + event_person_data['event_person_profile']['full_name'] = record.get('full_name') + + event_person_data['event_person_profile']['affiliations'] = record.get('affiliations') + + event_person_data['event_person_profile']['email'] = record.get('email') + event_person_data['event_person_profile']['phone'] = record.get('phone') + event_person_data['event_person_profile']['location'] = record.get('location') + + event_person_data['event_badge']['external_id'] = external_id + event_person_data['event_badge']['external_event_id'] = record.get('external_event_id') + event_person_data['event_badge']['external_registration_id'] = record.get('external_registration_id') + # event_person_data['event_badge']['external_reg_id'] = record.get('external_registration_id') # Deprecated + event_person_data['event_badge']['external_person_id'] = record.get('external_person_id') + # event_person_data['event_badge']['external_sys_id'] = record.get('external_person_id') # Deprecated + + event_person_data['event_badge']['enable'] = True + event_person_data['event_badge']['pronouns'] = record.get('pronouns') + event_person_data['event_badge']['informal_name'] = record.get('informal_name') + event_person_data['event_badge']['title_names'] = record.get('title_names') + event_person_data['event_badge']['given_name'] = record.get('given_name') + event_person_data['event_badge']['family_name'] = record.get('family_name') + event_person_data['event_badge']['designations'] = record.get('designations') + event_person_data['event_badge']['professional_title'] = record.get('professional_title') + + event_person_data['event_badge']['full_name'] = record.get('full_name') + + event_person_data['event_badge']['affiliations'] = record.get('affiliations') + + event_person_data['event_badge']['email'] = record.get('email') + event_person_data['event_badge']['phone'] = record.get('phone') + event_person_data['event_badge']['location'] = record.get('location') + + event_person_data['event_badge']['event_badge_template_id'] = 9 # record.get('event_badge_template_id') + + event_person_data['event_badge']['badge_type_code'] = record.get('badge_type_code') + event_person_data['event_badge']['badge_type'] = record.get('badge_type') + + # email = None + # city = None + # country_subdivision_code = None + # state_province = None + # state_province_abb = None + # country_alpha_2_code = None + # country = None + + # city = record.get('city') + # state_province = record.get('state_province') + # country = record.get('country') + # country_alpha_2_code = record.get('country_alpha_2_code') + + # if location := record.get('location'): + # else: + # location = f'{city} {state_province} {country_alpha_2_code}' + + event_badge_person_li.append(event_person_data) + event_badge_person_summary_li.append(event_person_summary) + # event_person_summary_li.append(event_person_summary_data) + loop_count = loop_count + 1 + + + sql_select_event_person = f""" + SELECT id AS event_person_id, id_random AS event_person_id_random, external_id AS event_person_external_id, external_event_id AS event_person_external_event_id, external_registration_id AS event_person_external_registration_id, external_person_id AS event_person_external_person_id, event_badge_id AS event_badge_id, event_person_profile_id AS event_person_profile_id, event_registration_id AS event_registration_id + FROM `event_person` AS `event_person` + WHERE event_person.event_id = :event_id + AND event_person.external_id = :external_id + /*LIMIT 1*/; + """ + + if event_person_result := sql_select(sql=sql_select_event_person, data=event_person_summary): + if isinstance(event_person_result, list): + log.error(f'Found more than one Event Person with the same External ID. Count: {len(event_person_result)}') + # return False + else: + event_person_id = event_person_result.get('event_person_id') + event_badge_id = event_person_result.get('event_badge_id') + event_person_profile_id = event_person_result.get('event_person_profile_id') + log.info(f'Found Event Person. Updating existing... Event Person ID: {event_person_id}') + if create_event_person_obj_result := create_update_event_person_obj_v4( + event_person_dict_obj = event_person_data, + event_person_id = event_person_id, + account_id = account_id, + event_id = event_id, + event_badge_id = event_badge_id, + event_person_profile_id = event_person_profile_id, + # create_sub_obj = create_sub_obj, + # fail_any = fail_any, + # return_outline = False, + ): + event_person_id = create_event_person_obj_result + log.warning(f'Event Person updated. Event Person ID: {event_person_id}') + else: + log.warning(f'Event Person not updated. Event Person ID: {event_person_id}') + log.debug(event_badge_obj_in_result) + # return False + else: + log.info('No Event Person found. Creating new...') + + if create_event_person_obj_result := create_update_event_person_obj_v4( + event_person_dict_obj = event_person_data, + account_id = account_id, + event_id = event_id, + # create_sub_obj = create_sub_obj, + # fail_any = fail_any, + # return_outline = False, + ): + event_person_id = create_event_person_obj_result + log.warning(f'Event Person created. Event Person ID: {event_person_id}') + else: + log.warning(f'Event Person not created.') + log.debug(event_badge_obj_in_result) + # return False + + + + if return_detail: + return mk_resp(data=event_badge_person_li, status_message=f'Importing badges from file. Found {len(person_li)} badges.', response=commons.response) + else: + return mk_resp(data=event_badge_person_summary_li, status_message=f'Checked for badges from file. Found {len(event_badge_person_li)} badges.', response=commons.response) \ No newline at end of file diff --git a/app/routers/event_exhibit_tracking.py b/app/routers/event_exhibit_tracking.py index 4c91581..e9000aa 100644 --- a/app/routers/event_exhibit_tracking.py +++ b/app/routers/event_exhibit_tracking.py @@ -271,13 +271,13 @@ async def get_event_exhibit_obj_tracking_list( data_dict['person_designations'] = data_dict.pop('event_badge_designations') data_dict['person_professional_title'] = data_dict.pop('event_badge_professional_title') - data_dict['person_display_professional_title'] = data_dict.pop('event_badge_display_professional_title') + data_dict['person_professional_title_override'] = data_dict.pop('event_badge_professional_title_override') - data_dict['person_display_name'] = data_dict.pop('event_badge_display_name') data_dict['person_full_name'] = data_dict.pop('event_badge_full_name') + data_dict['person_full_name_override'] = data_dict.pop('event_badge_full_name_override') data_dict['person_affiliations'] = data_dict.pop('event_badge_affiliations') - data_dict['person_display_affiliations'] = data_dict.pop('event_badge_display_affiliations') + data_dict['person_affiliations_override'] = data_dict.pop('event_badge_affiliations_override') data_dict['person_email'] = data_dict.pop('event_badge_email') @@ -290,7 +290,7 @@ async def get_event_exhibit_obj_tracking_list( if 'event_badge_address_line_3' in data_dict: data_dict['person_address_line_3'] = data_dict.pop('event_badge_address_line_3') else: data_dict['person_address_line_3'] = None - + if 'event_badge_city' in data_dict: data_dict['person_city'] = data_dict.pop('event_badge_city') else: data_dict['person_city'] = None @@ -319,9 +319,9 @@ async def get_event_exhibit_obj_tracking_list( if 'event_badge_location' in data_dict: data_dict['person_location'] = data_dict.pop('event_badge_location') else: data_dict['person_location'] = None - if 'event_badge_display_location' in data_dict: - data_dict['person_display_location'] = data_dict.pop('event_badge_display_location') - else: data_dict['person_display_location'] = None + if 'event_badge_location_override' in data_dict: + data_dict['person_location_override'] = data_dict.pop('event_badge_location_override') + else: data_dict['person_location_override'] = None data_dict_list_for_export.append(data_dict) else: @@ -340,13 +340,13 @@ async def get_event_exhibit_obj_tracking_list( 'person_family_name', 'person_designations', - 'person_professional_title', 'person_display_professional_title', + 'person_professional_title', 'person_professional_title_override', - 'person_display_name', + 'person_name_override', 'person_full_name', 'person_affiliations', - 'person_display_affiliations', + 'person_affiliations_override', 'person_email', @@ -365,11 +365,11 @@ async def get_event_exhibit_obj_tracking_list( 'person_country', 'person_location', - 'person_display_location', + 'person_location_override', 'priority', 'sort', - + 'exhibitor_notes', 'created_on', diff --git a/app/routers/event_person.py b/app/routers/event_person.py index 9ff5b17..e686bc1 100644 --- a/app/routers/event_person.py +++ b/app/routers/event_person.py @@ -184,7 +184,7 @@ async def v2_post_event_person_new( full_name = f'{given_name} {family_name}' elif given_name: full_name = f'{given_name}' - display_name = event_person_new_init.person_display_name + full_name_override = event_person_new_init.person_full_name_override email = event_person_new_init.email if new_password := event_person_new_init.new_password: @@ -200,7 +200,7 @@ async def v2_post_event_person_new( person_new['given_name'] = given_name person_new['family_name'] = family_name person_new['full_name'] = full_name - person_new['display_name'] = display_name + person_new['display_name'] = full_name_override # NOTE This is using full_name_override for display_name person_new['affiliations'] = affiliations # New person contact diff --git a/app/routers/event_reports.py b/app/routers/event_reports.py index eace506..427976d 100644 --- a/app/routers/event_reports.py +++ b/app/routers/event_reports.py @@ -80,7 +80,7 @@ async def event_id_rpt_presenter_links( if create_export: # column_name_li = ['order_id_random', 'order_line_id_random', '', 'product_name', 'quantity', 'amount', 'dollar_amount', 'person_email'] - # column_name_li = ['order_line_id_random', 'order_id_random', 'product_id_random', 'product_type', 'product_name', 'product_unit_price', 'product_recurring', 'curr_product_id_random', 'curr_product_type', 'curr_product_type_name', 'curr_product_name', 'name', 'quantity', 'amount', 'dollar_amount', 'recurring', 'message', 'person_id_random', 'person_given_name', 'person_family_name', 'person_display_name', 'person_full_name', 'person_contact_email', 'person_contact_cc_email', 'person_contact_phone_mobile', 'person_contact_phone_home', 'person_contact_phone_office', 'person_contact_phone_land', 'person_contact_phone_fax', 'person_contact_phone_other', 'person_contact_address_name', 'person_contact_address_organization_name', 'person_contact_address_line_1', 'person_contact_address_line_2', 'person_contact_address_line_3', 'person_contact_address_city', 'person_contact_address_country_subdivision_code', 'person_contact_address_state_province', 'person_contact_address_postal_code', 'person_contact_address_country_alpha_2_code', 'person_contact_address_country_name', 'person_contact_address_country', 'order_status', 'order_created_on', 'order_updated_on', 'created_on', 'updated_on'] + # column_name_li = ['order_line_id_random', 'order_id_random', 'product_id_random', 'product_type', 'product_name', 'product_unit_price', 'product_recurring', 'curr_product_id_random', 'curr_product_type', 'curr_product_type_name', 'curr_product_name', 'name', 'quantity', 'amount', 'dollar_amount', 'recurring', 'message', 'person_id_random', 'person_given_name', 'person_family_name', 'person_full_name', 'person_full_name_override', 'person_contact_email', 'person_contact_cc_email', 'person_contact_phone_mobile', 'person_contact_phone_home', 'person_contact_phone_office', 'person_contact_phone_land', 'person_contact_phone_fax', 'person_contact_phone_other', 'person_contact_address_name', 'person_contact_address_organization_name', 'person_contact_address_line_1', 'person_contact_address_line_2', 'person_contact_address_line_3', 'person_contact_address_city', 'person_contact_address_country_subdivision_code', 'person_contact_address_state_province', 'person_contact_address_postal_code', 'person_contact_address_country_alpha_2_code', 'person_contact_address_country_name', 'person_contact_address_country', 'order_status', 'order_created_on', 'order_updated_on', 'created_on', 'updated_on'] column_name_li = [ 'event_presenter_id_random',