From 882c7408809d8f977717c54f8b8d1ce81b12e505 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 16 Jun 2025 19:22:02 -0400 Subject: [PATCH] Finally getting rid of the old display_name fields. Trying to use full_name and full_name_override everywhere. --- app/methods/person_methods.py | 2 +- app/models/event_person_models.py | 6 +- app/models/order_line_models.py | 3 +- app/models/order_line_models_v3.py | 6 +- app/models/person_models.py | 8 +- app/routers/event_importing.py | 170 ++++++++++++++++++++--------- 6 files changed, 136 insertions(+), 59 deletions(-) diff --git a/app/methods/person_methods.py b/app/methods/person_methods.py index 3f71408..150a48d 100644 --- a/app/methods/person_methods.py +++ b/app/methods/person_methods.py @@ -1837,7 +1837,7 @@ def handle_email_person_auth_key_url( from_email = account_cfg.default_no_reply_email from_name = account_cfg.default_no_reply_name - to_name = person_obj.display_name + to_name = person_obj.full_name to_email = person_obj.email bcc_email = account_cfg.confirm_email diff --git a/app/models/event_person_models.py b/app/models/event_person_models.py index 63fba56..3e2e444 100644 --- a/app/models/event_person_models.py +++ b/app/models/event_person_models.py @@ -126,8 +126,9 @@ class Event_Person_Base(BaseModel): person_given_name: Optional[str] person_middle_name: Optional[str] person_family_name: Optional[str] - person_display_name: Optional[str] person_full_name: Optional[str] + person_full_name_override: Optional[str] + # person_display_name: Optional[str] person_affiliations: Optional[str] person_email: Optional[str] @@ -300,7 +301,8 @@ class Event_Person_New_Base(BaseModel): person_middle_name: Optional[str] person_family_name: Optional[str] person_full_name: Optional[str] - person_display_name: Optional[str] + person_full_name_override: Optional[str] + # person_display_name: Optional[str] # affiliations: Optional[str] # One or more affiliations with organizations, companies, and other groups diff --git a/app/models/order_line_models.py b/app/models/order_line_models.py index 32ed26f..5925ae8 100644 --- a/app/models/order_line_models.py +++ b/app/models/order_line_models.py @@ -70,8 +70,9 @@ class Order_Line_Base(BaseModel): for_person_id_random: Optional[str] for_person_given_name: Optional[str] # Dynamic from v_order_line for_person_family_name: Optional[str] # Dynamic from v_order_line - for_person_display_name: Optional[str] # Dynamic from v_order_line for_person_full_name: Optional[str] # Dynamic from v_order_line + for_person_full_name_override: Optional[str] # Dynamic from v_order_line + # for_person_display_name: Optional[str] # Dynamic from v_order_line name: Optional[str] # Should be the same as product_name above quantity: int = Field(0, ge=0, lt=150) diff --git a/app/models/order_line_models_v3.py b/app/models/order_line_models_v3.py index 7e73653..11cc54c 100644 --- a/app/models/order_line_models_v3.py +++ b/app/models/order_line_models_v3.py @@ -71,8 +71,9 @@ class Order_Line_Base(BaseModel): for_person_id_random: Optional[str] for_person_given_name: Optional[str] # Dynamic from v_order_line for_person_family_name: Optional[str] # Dynamic from v_order_line - for_person_display_name: Optional[str] # Dynamic from v_order_line for_person_full_name: Optional[str] # Dynamic from v_order_line + for_person_full_name_override: Optional[str] # Dynamic from v_order_line + # for_person_display_name: Optional[str] # Dynamic from v_order_line name: Optional[str] # Should be the same as product_name above quantity: int = Field(0, ge=0, lt=150) @@ -248,8 +249,9 @@ class Order_Line_Full_Detail_Base(Order_Line_Base): person_id_random: Optional[str] person_given_name: Optional[str] person_family_name: Optional[str] - person_display_name: Optional[str] person_full_name: Optional[str] + person_full_name_override: Optional[str] + # person_display_name: Optional[str] person_contact_id: Optional[int] person_contact_id_random: Optional[str] diff --git a/app/models/person_models.py b/app/models/person_models.py index 97bb03e..e3a9b1c 100644 --- a/app/models/person_models.py +++ b/app/models/person_models.py @@ -59,11 +59,11 @@ class Person_Base(BaseModel): professional_title: Optional[str] # Professional title - display_name: Optional[str] # NOTE: This will be changed to full_name_override to match event_badge, event_presenter, and event_profile - informal_display_name: Optional[str] # Custom what they want for informal public display - professional_display_name: Optional[str] # Custom what they want for professional public display. This should include professional title. + # display_name: Optional[str] # NOTE: This will be changed to full_name_override to match event_badge, event_presenter, and event_profile + # informal_display_name: Optional[str] # Custom what they want for informal public display + # professional_display_name: Optional[str] # Custom what they want for professional public display. This should include professional title. - preferred_display_name: Optional[str] # '', 'informal', 'professional' + preferred_display_name: Optional[str] # Which name variant to display? '', 'informal', 'professional', etc # BEGIN # Auto created name variations first_last_name: Optional[str] # With SQL view? diff --git a/app/routers/event_importing.py b/app/routers/event_importing.py index b5cd2e2..74a6957 100644 --- a/app/routers/event_importing.py +++ b/app/routers/event_importing.py @@ -341,6 +341,9 @@ async def event_importing_program_data( begin_at: int = 0, end_at: int = 20000, + allow_update_event_session: bool = True, + link_sync_person: bool = False, + commons: Common_Route_Params = Depends(common_route_params), ): log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL @@ -684,7 +687,7 @@ async def event_importing_program_data( log.debug(event_session_data) - if allow_updates: + if allow_updates and allow_update_event_session: if event_session_obj_up_result := sql_update(data=event_session_data, table_name='event_session'): log.debug(event_session_obj_up_result) else: @@ -798,7 +801,7 @@ async def event_importing_program_data( # INSERT or UPDATE event_presenter - # NEW - Way to handle a semicolon delimited list of presenters in a single cell + # Handle a semicolon delimited list of presenters in a single cell if presenter_full_name_li := record.get('presenter_full_name_li', None): log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(f'Found presenter list {presenter_full_name_li}') @@ -810,7 +813,7 @@ async def event_importing_program_data( account_id = account_id, event_id = event_id, event_session_id = event_session_id, - event_presentation_id = event_presentation_id, presenter_full_name=presenter_full_name + event_presentation_id = event_presentation_id, presenter_full_name = presenter_full_name ) presentation_summary_data = event_presenter_record_results event_presenter_li.append(presentation_summary_data) @@ -823,8 +826,8 @@ async def event_importing_program_data( event_program_data_li.append(data) log.info(f'Record processed: Session: {event_session_id} Presentation: {event_presentation_id} Presenter list: {presenter_full_name_li}') + # Handle a single presenter per row else: - # OLD - Way to handle a single presenter per row data['event_presenter_external_id'] = event_presenter_external_id sql = f""" @@ -905,6 +908,19 @@ async def event_importing_program_data( data['event_presenter_number'] = event_presenter_number data['event_presenter_full_name'] = event_presenter_full_name + if link_sync_person: + event_presenter_record_results = process_event_presenter_w_full_name( + account_id = account_id, + event_id = event_id, + event_session_id = event_session_id, + event_presentation_id = event_presentation_id, presenter_full_name = event_presenter_full_name, + event_presenter_id = event_presenter_id, + # sync_external_id = False, # WARNING: True can break future import updates. + ) + presentation_summary_data = event_presenter_record_results + data['person_link_sync_summary'] = presentation_summary_data + # event_presenter_li.append(presentation_summary_data) + # End of the loop. Append to program list data results. event_program_data_li.append(data) @@ -917,7 +933,7 @@ async def event_importing_program_data( # ### BEGIN ### Event Importing ### pre_program_person_data_import() ### # This is the new import endpoint for pre-program person data. Currently this is intended for use with LCI. # Required fields: account_id (from commons header), event_id, file -# Updated 2024-06-09 +# Updated 2025-06-13 @router.post('/event/{event_id}/importing/pre_program_person_data', response_model=Resp_Body_Base) async def pre_program_data_import( event_id: str = Path(min_length=11, max_length=22), @@ -970,9 +986,11 @@ async def pre_program_data_import( 'email': str, 'Email Address': str, 'given_name': str, 'Given Name': str, 'First Name': str, 'given_name_[first]' : str, + 'given_name_(first)': str, 'middle_name': str, 'Middle Name': str, 'family_name': str, 'Family Name': str, 'Last Name': str, 'family_name_[last]': str, + 'family_name_(last)': str, 'title_names': str, 'Title Names': str, 'Prefix': str, 'informal_name': str, 'Nickname': str, 'professional_title': str, 'Professional Title': str, @@ -990,11 +1008,13 @@ async def pre_program_data_import( 'Email Address': 'email', 'Given Name': 'given_name', 'given_name_[first]': 'given_name', + 'given_name_(first)': 'given_name', 'First Name': 'given_name', 'Middle Name': 'middle_name', 'Family Name': 'family_name', 'Last Name': 'family_name', 'family_name_[last]': 'family_name', + 'family_name_(last)': 'family_name', 'Title Names': 'title_names', 'Prefix': 'title_names', 'Nickname': 'informal_name', @@ -1034,7 +1054,7 @@ async def pre_program_data_import( # ### BEGIN ### Event Importing ### process_person_data() ### -# Updated 2024-06-09 +# Updated 2025-06-13 def process_person_data(account_id, source_code, record): log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) @@ -1142,7 +1162,16 @@ def process_person_data(account_id, source_code, record): # This will try to look up the person record based on their full name and then update the event presenter record. If the person record is not found, it will return False. If the person record is found, it will return the person record data. # Should we also pass event_id and event_session_id? -def process_event_presenter_w_full_name(account_id, event_id, event_session_id, event_presentation_id, presenter_full_name): +def process_event_presenter_w_full_name( + account_id, event_id, + event_session_id, + event_presentation_id, + presenter_full_name, + event_presenter_id = None, + link_person = True, # At least one of these should be True + sync_person = True, # At least one of these should be True + sync_external_id = False, # Changing the external_id can break future imports + ): log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) @@ -1177,51 +1206,22 @@ def process_event_presenter_w_full_name(account_id, event_id, event_session_id, # Second - SQL SELECT to find the event presenter record based on the event_presentation_id and the person_id returned from the first SQL SELECT # If the event presenter record is found, UPDATE the record with the person_id # if event_presenter_rec := sql_select(table_name='v_event_presenter', field_name='event_presentation_id', field_value=event_presentation_id): - qry_data = { - 'event_presentation_id': event_presentation_id, - 'person_id': person_id, - } - if event_presenter_rec := sql_select(table_name='v_event_presenter', data=qry_data, log_lvl=logging.INFO): - if not isinstance(event_presenter_rec, list): - event_presenter_id = event_presenter_rec.get('event_presenter_id', None) - event_presenter_id_random = event_presenter_rec.get('event_presenter_id_random', None) - else: - log.warning('Found more than one record') - log.warning(event_presenter_rec) - return False + + # First try the easy option by using the known presenter ID + if event_presenter_id: data = {} - data['full_name'] = person_rec['full_name'] - data['email'] = person_rec['primary_email'] - - summary_data['event_presenter_id'] = event_presenter_id - - if event_presenter_obj_up_result := sql_update(data=data, table_name='event_presenter', record_id=event_presenter_id): - log.debug(event_presenter_obj_up_result) - else: - log.warning(event_presenter_obj_up_result) - return False - # If the event presenter record is not found, INSERT a new record with the person_id - else: - data = {} - data['event_id'] = event_id - data['event_session_id'] = event_session_id - data['event_presentation_id'] = event_presentation_id - # WARNING: person_id does not exist in the event_presenter table. This is a new field that will be added. It will make more sense to have a person_profile table that combines the person, event_badge, and event_presenter tables. - data['person_id'] = person_id # WARNING! - - # This should fill out the event_presenter record based on the person record. This will likely be a new table named person_profile. It will likely be a combination of the person, event_badge, and event_presenter tables. - data['external_id'] = person_rec['external_id'] - # Do we know the presenter code (or number)? - # Do we know for_type or for_id? + # NOTE: If the external_id changes from what was originally imported, it will no longer import that record correctly. A new one will be created. + if sync_external_id: + data['external_id'] = person_rec['external_id'] + data['person_id'] = person_id data['informal_name'] = person_rec['informal_name'] data['title_names'] = person_rec['title_names'] data['given_name'] = person_rec['given_name'] data['middle_name'] = person_rec['middle_name'] data['family_name'] = person_rec['family_name'] - data['full_name'] = person_rec['full_name'] data['designations'] = person_rec['designations'] data['professional_title'] = person_rec['professional_title'] @@ -1229,12 +1229,84 @@ def process_event_presenter_w_full_name(account_id, event_id, event_session_id, data['affiliations'] = person_rec['affiliations'] data['email'] = person_rec['primary_email'] - if event_presenter_obj_in_result := sql_insert(data=data, table_name='event_presenter'): - log.debug(event_presenter_obj_in_result) - event_presenter_id = event_presenter_obj_in_result - summary_data['event_presenter_id'] = event_presenter_id - else: - log.warning(event_presenter_obj_in_result) + summary_data['person_id'] = person_id + summary_data['event_presenter_id'] = event_presenter_id + if sync_person: + if event_presenter_obj_up_result := sql_update(data=data, table_name='event_presenter', record_id=event_presenter_id): + log.debug(event_presenter_obj_up_result) + else: + log.warning(event_presenter_obj_up_result) + return False + else: + log.info('Skipping update of event_presenter record') + + # Second try looking up with the known presentation ID and found person ID + else: + + # Check if the presenter is already linked to a person record. UPDATE if found. + qry_data = { + 'event_presentation_id': event_presentation_id, + 'person_id': person_id, + } + if event_presenter_rec := sql_select(table_name='v_event_presenter', data=qry_data, log_lvl=logging.INFO): + if not isinstance(event_presenter_rec, list): + event_presenter_id = event_presenter_rec.get('event_presenter_id', None) + event_presenter_id_random = event_presenter_rec.get('event_presenter_id_random', None) + else: + log.warning('Found more than one record') + log.warning(event_presenter_rec) + return False + + data = {} + data['full_name'] = person_rec['full_name'] + data['email'] = person_rec['primary_email'] + + summary_data['event_presenter_id'] = event_presenter_id + + if sync_person: + if event_presenter_obj_up_result := sql_update(data=data, table_name='event_presenter', record_id=event_presenter_id): + log.debug(event_presenter_obj_up_result) + else: + log.warning(event_presenter_obj_up_result) + return False + else: + log.info('Skipping update of event_presenter record') + + # If the event presenter record is not found, INSERT a new record with the person_id to link them. + else: + data = {} + data['event_id'] = event_id + data['event_session_id'] = event_session_id + data['event_presentation_id'] = event_presentation_id + # WARNING: person_id does not exist in the event_presenter table. This is a new field that will be added. It will make more sense to have a person_profile table that combines the person, event_badge, and event_presenter tables. + data['person_id'] = person_id # WARNING! + + # This should fill out the event_presenter record based on the person record. This will likely be a new table named person_profile. It will likely be a combination of the person, event_badge, and event_presenter tables. + data['external_id'] = person_rec['external_id'] + # Do we know the presenter code (or number)? + # Do we know for_type or for_id? + + + data['informal_name'] = person_rec['informal_name'] + data['title_names'] = person_rec['title_names'] + data['given_name'] = person_rec['given_name'] + data['middle_name'] = person_rec['middle_name'] + data['family_name'] = person_rec['family_name'] + data['full_name'] = person_rec['full_name'] + + data['designations'] = person_rec['designations'] + data['professional_title'] = person_rec['professional_title'] + + data['affiliations'] = person_rec['affiliations'] + data['email'] = person_rec['primary_email'] + + if link_person: + if event_presenter_obj_in_result := sql_insert(data=data, table_name='event_presenter'): + log.debug(event_presenter_obj_in_result) + event_presenter_id = event_presenter_obj_in_result + summary_data['event_presenter_id'] = event_presenter_id + else: + log.warning(event_presenter_obj_in_result) return summary_data \ No newline at end of file