diff --git a/app/methods/e_cvent_methods.py b/app/methods/e_cvent_methods.py index 36cc8f6..db5d6bb 100644 --- a/app/methods/e_cvent_methods.py +++ b/app/methods/e_cvent_methods.py @@ -1,5 +1,5 @@ from __future__ import annotations -import datetime, json, pprint, pytz, random, requests, secrets, time +import datetime, json, pprint, pytz, random, requests, secrets, string, time from requests.auth import HTTPBasicAuth from typing import Dict, List, Optional, Set, Union @@ -8,7 +8,8 @@ from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, v from app.db_sql import redis_lookup_id_random, sql_insert, sql_select, sql_update from app.lib_general import log, logging, logger_reset, secure_hash_string, verify_secure_hash_string -from app.methods.person_methods import get_person_rec_w_external_id, load_person_obj, update_person_kiss +from app.methods.person_methods import create_person_kiss, get_person_rec_list, get_person_rec_w_external_id, load_person_obj, update_person_kiss +from app.methods.membership_person_methods import create_membership_person_obj, update_membership_person_obj app = {} @@ -78,10 +79,8 @@ def get_access_token(): log.debug(api) - # f = open("api_access.txt", "wb") - # f.write(pprint.pformat(api, indent=2, width=160)) - # pickle.dump(api, f) - # f.close() + log.warning('Sleeping for 1 second to avoid Cvent rate limit...') + time.sleep(1.5) return api @@ -115,10 +114,12 @@ def get_contact_custom_field_list(api): # Updated 2022-01-31 @logger_reset -def get_contact_list(api, external_id: str=False): +def get_contact_list(external_id: str=None, email: str=None): log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) + get_access_token() + endpoint = '/contacts' uri = api['base_url']+endpoint @@ -126,21 +127,21 @@ def get_contact_list(api, external_id: str=False): # customField.609ab766-7d79-4a9d-a72c-f126412659ee eq external_id params = {} - if external_id: params['filter'] = f"customField.609ab766-7d79-4a9d-a72c-f126412659ee eq '{external_id}'" + if external_id: + params['filter'] = f"deleted eq 'False' and customField.609ab766-7d79-4a9d-a72c-f126412659ee eq '{external_id}'" + elif email: + params['filter'] = f"deleted eq 'False' and email eq '{email}'" elif external_id is None: params['filter'] = f"deleted eq 'False' and customField.609ab766-7d79-4a9d-a72c-f126412659ee lt '1'" - else: params['filter'] = f"deleted eq 'False'" + else: + params['filter'] = f"deleted eq 'False'" resp = requests.get(url=uri, headers=api['headers'], params=params) response_data = resp.json() + log.debug(json.dumps(response_data, indent=2, default=str)) - # if external_id: filename = f'contact_{external_id}.txt' - # elif external_id is None: filename = f'contact_list_no_external_id.txt' - # else: filename = 'contact_list.txt' - - # f = open(filename, 'w') - # f.write(pprint.pformat(response_data, indent=2, width=160)) + if 'message' in response_data and response_data['message'] == 'Too Many Requests': return False return response_data @@ -153,19 +154,23 @@ def get_recent_contact_list(created_on=None, updated_on=None): get_access_token() - log.warning('Sleeping for 1 second to avoid Cvent rate limit...') - time.sleep(1) - endpoint = f'/contacts' uri = api['base_url']+endpoint params = {} - if created_on: + if created_on and updated_on: created_on_str = created_on.isoformat() - print(f'Created On: {created_on_str}') + updated_on_str = updated_on.isoformat() + log.info(f'Created On: {created_on_str}') + log.info(f'Updated On: {updated_on_str}') + params['filter'] = f"deleted eq 'False' and created gt '{created_on_str}Z' or lastModified gt '{updated_on_str}Z'" + elif created_on: + created_on_str = created_on.isoformat() + log.info(f'Created On: {created_on_str}') params['filter'] = f"deleted eq 'False' and created gt '{created_on_str}Z'" elif updated_on: - print(f'Updated On: {created_on_str}') + updated_on_str = updated_on.isoformat() + log.info(f'Updated On: {updated_on_str}') params['filter'] = f"deleted eq 'False' and lastModified gt '{updated_on_str}Z'" else: log.warning('Created On or Updated On is requried. Returing False') @@ -174,7 +179,7 @@ def get_recent_contact_list(created_on=None, updated_on=None): resp = requests.get(url=uri, headers=api['headers'], params=params) response_data = resp.json() - log.debug(response_data) + log.debug(json.dumps(response_data, indent=2, default=str)) if 'message' in response_data and response_data['message'] == 'Too Many Requests': return False @@ -191,8 +196,8 @@ def get_contact_id(contact_id: str): # else: get_access_token() get_access_token() - log.warning('Sleeping for 1 second to avoid Cvent rate limit...') - time.sleep(1) + # log.warning('Sleeping for 1 second to avoid Cvent rate limit...') + # time.sleep(1) endpoint = f'/contacts/{contact_id}' uri = api['base_url']+endpoint @@ -202,7 +207,7 @@ def get_contact_id(contact_id: str): resp = requests.get(url=uri, headers=api['headers'], params=params) response_data = resp.json() - log.debug(response_data) + log.debug(json.dumps(response_data, indent=2, default=str)) if 'message' in response_data and response_data['message'] == 'Too Many Requests': return False @@ -242,7 +247,7 @@ def modify_contact_id(contact_id: str, field_list: list=[], custom_field_id: str resp = requests.patch(url=uri, headers=api['headers'], params=params, json=data) response_data = resp.json() - log.debug(response_data) + log.debug(json.dumps(response_data, indent=2, default=str)) if 'message' in response_data and response_data['message'] == 'Too Many Requests': return False @@ -261,6 +266,7 @@ def create_update_aether_person( log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) + # Important variables used more than once. person_external_id = None if custom_field_list := cvent_contact_obj.get('customFields'): # List for custom_field in custom_field_list: @@ -339,12 +345,13 @@ def create_update_aether_person( person_data['user'] = user_data if cvent_contact_obj.get('type'): - membership_type_cvent_id = cvent_contact_obj.get('type').get('id') - membership_type_cvent_name = cvent_contact_obj.get('type').get('name') - log.info(f'Found Cvent Membership Type Named: {membership_type_cvent_name}') + # NOTE: Should this be renamed to contact_type_id and contact_type_name??? + cvent_contact_type_id = cvent_contact_obj.get('type').get('id') + cvent_contact_type_name = cvent_contact_obj.get('type').get('name') + log.info(f'Found Cvent Contact Type Named: {cvent_contact_type_name}') else: - membership_type_cvent_id = None - membership_type_cvent_name = None + cvent_contact_type_id = None + cvent_contact_type_name = None # 'id': '5EB898D8-C253-482C-A93A-0B6667C26E04', 'name': 'Al-Anon Member' # 'id': 'A20358C5-0F6C-47AF-9843-BA9483A9D767', 'name': 'Al-Anon Non-Member' @@ -362,34 +369,44 @@ def create_update_aether_person( # 'id': 'DA17F721-9924-43E3-A31F-C567BA96DC64', 'name': 'IDAA Teen (13-19 years)' # 'id': 'C49439B3-5AE6-496F-A0AD-4CCB1A9000E3', 'name': 'Spouse/SO Guest Registration' - # Currently in use for IDAA: + # Currently in use Member Type names for IDAA: # Member Type = Member Contact Type - # Annual Contribution(s) = Attendee - # Doctoral Qualifying Member(s) = Member - # Student Member(s) = Student Member + # Al-Anon Member(s) = "Al-Anon Member" and "Al-Anon Non-Member" + # Annual Contribution(s) = "Attendee" and "Non-Member" + # Doctoral Qualifying Member(s) = "Member" and "Non-Member" + # Student Member(s) = "Student Member" and "Student Non-member" + # NOTE: "Student Non-member" is NOT "Student Non-Member" (the lowercase m) membership_person_data = {} membership_person_type_data = {} - if membership_type_cvent_name: - if membership_type_cvent_name == 'Al-Anon Member' or membership_type_cvent_name == 'Al-Anon Members': + # NOTE: Should this be renamed to contact_type_id and contact_type_name??? + # Technically the membership type naming is slightly different and more of them. + # if cvent_contact_type_name: + if cvent_contact_obj.get('membership'): + if cvent_contact_type_name == 'Al-Anon Member' or cvent_contact_type_name == 'Al-Anon Members': membership_person_type_data['membership_type_id'] = 6 membership_person_type_data['product_id'] = 13 membership_person_type_data['level'] = 1 - elif membership_type_cvent_name == 'Annual Contribution' or membership_type_cvent_name == 'Annual Contributions' or membership_type_cvent_name == 'Attendee': # Unsure... making affiliate + elif cvent_contact_type_name == 'Annual Contribution' or cvent_contact_type_name == 'Annual Contributions' or cvent_contact_type_name == 'Attendee': # Unsure... making affiliate membership_person_type_data['membership_type_id'] = 8 membership_person_type_data['product_id'] = 13 membership_person_type_data['level'] = 3 - elif membership_type_cvent_name == 'Doctoral Qualifying Member' or membership_type_cvent_name == 'Doctoral Qualifying Members' or membership_type_cvent_name == 'Member': + elif cvent_contact_type_name == 'Doctoral Qualifying Member' or cvent_contact_type_name == 'Doctoral Qualifying Members' or cvent_contact_type_name == 'Member': membership_person_type_data['membership_type_id'] = 5 membership_person_type_data['product_id'] = 4 membership_person_type_data['level'] = 1 - elif membership_type_cvent_name == 'Student Member' or membership_type_cvent_name == 'Student Members': + elif cvent_contact_type_name == 'Student Member' or cvent_contact_type_name == 'Student Members': membership_person_type_data['membership_type_id'] = 7 membership_person_type_data['product_id'] = 14 membership_person_type_data['level'] = 1 + elif cvent_contact_type_name in ['Al-Anon Non-Member', 'Non-Member', 'Student Non-member', 'Student Non-Member']: + membership_person_type_data['membership_type_id'] = 8 + membership_person_type_data['product_id'] = 13 + membership_person_type_data['level'] = 3 else: - log.error(f'Unknown Membership Type Name from Cvent: {membership_type_cvent_name}') - return False + log.error(f'Unknown Contact Type Name from Cvent: {cvent_contact_type_name}') + cvent_contact_type_id = None + cvent_contact_type_name = None membership_person_type_data['first_start_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('joined'), '%Y-%m-%d') if cvent_contact_obj.get('membership').get('lastRenewal'): @@ -461,7 +478,7 @@ def create_update_aether_person( time.sleep(1) contact_mod_result = modify_contact_id( - contact_id = cvent_person_id, # This is the Cvent Contact UUID for a person + contact_id = cvent_contact_id, # This is the Cvent Contact UUID for a person # field_list = field_list, custom_field_id = custom_field_id, custom_field_value = custom_field_value, @@ -511,7 +528,7 @@ def create_update_aether_person( # return False # ### TESTING BREAK POINT ### - if membership_type_cvent_id and membership_person_id: + if cvent_contact_type_id and membership_person_id: # membership_person_id = person_obj.membership_person.id membership_person_data['id'] = membership_person_id membership_person_data['membership_person_type']['id'] = membership_person_type_id @@ -519,7 +536,7 @@ def create_update_aether_person( log.info(f'Updated Membership Person ID: {membership_person_id}') else: log.info(f'Did not update Membership Person ID: {membership_person_id}') - elif membership_type_cvent_id: + elif cvent_contact_type_id: if create_membership_person_obj_result := create_membership_person_obj(account_id=account_id, person_id=person_id, membership_person_dict_obj=membership_person_data): membership_person_id = create_membership_person_obj_result log.info(f'Created Membership Person ID: {membership_person_id}') @@ -531,8 +548,8 @@ def create_update_aether_person( person_data['membership_person'] = membership_person_data log.debug(json.dumps(person_data, indent=2, default=str)) - person_obj = load_person_obj(person_id=person_id, inc_address=True, inc_contact=True, inc_membership_person=True, inc_membership_person_type=True, inc_user=True) - log.debug(person_obj) + # person_obj = load_person_obj(person_id=person_id, inc_address=True, inc_contact=True, inc_membership_person=True, inc_membership_person_type=True, inc_user=True) + # log.debug(person_obj) - return person_obj # True + return person_id # True # ### END ### API External Cvent ### create_update_aether_person() ### diff --git a/app/models/contact_models.py b/app/models/contact_models.py index ec925d5..c051c91 100644 --- a/app/models/contact_models.py +++ b/app/models/contact_models.py @@ -124,13 +124,16 @@ class Contact_Base(BaseModel): return redis_lookup_id_random(record_id_random=id_random, table_name='address') return None + # NOTE: Linked Address ID is actually the old contact.address_id + # This should no longer be used... @validator('linked_address_id', always=True) def linked_address_id_lookup(cls, v, values, **kwargs): log.setLevel(logging.WARNING) log.debug(locals()) - if values.get('linked_address_id_random', None): - return redis_lookup_id_random(record_id_random=values['linked_address_id_random'], table_name='linked_address') + if isinstance(v, int) and v > 0: return v + elif id_random := values.get('linked_address_id_random'): + return redis_lookup_id_random(record_id_random=id_random, table_name='address') return None @validator('for_id', pre=True, always=True) diff --git a/app/routers/e_cvent.py b/app/routers/e_cvent.py index 56b2e92..0b36fbe 100644 --- a/app/routers/e_cvent.py +++ b/app/routers/e_cvent.py @@ -9,7 +9,7 @@ from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, 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.e_cvent_methods import create_update_aether_person, get_access_token, get_contact_custom_field_list, get_contact_list, get_contact_id, modify_contact_id +from app.methods.e_cvent_methods import create_update_aether_person, get_access_token, get_contact_custom_field_list, get_contact_list, get_contact_id, get_recent_contact_list, modify_contact_id from app.methods.person_methods import create_person_kiss, get_person_rec_list, get_person_rec_w_external_id, load_person_obj, update_person_kiss from app.methods.membership_person_methods import create_membership_person_obj, update_membership_person_obj @@ -20,11 +20,59 @@ from app.models.person_models import Person_Base router = APIRouter() -# ### BEGIN ### API Cvent ### get_person() ### +# ### BEGIN ### API Cvent ### get_person_recent_changes() ### # Updated 2022-02-01 -@router.get('/person/{cvent_person_id}', response_model=Resp_Body_Base) +@router.get('/person/recent_changes', response_model=Resp_Body_Base) +async def get_person_recent_changes( + from_datetime: datetime.datetime = datetime.datetime.utcnow() + datetime.timedelta(minutes=-90), # for Cvent "created" and "lastModified" + to_datetime: datetime.datetime = None, # for Cvent "created" and "lastModified" + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + account_id = commons.x_account_id + + if cvent_contact_list_result := get_recent_contact_list( + created_on = from_datetime, + updated_on = from_datetime + ): + log.debug(cvent_contact_list_result) + else: + log.info(f'Something went wrong while trying to get recently created or updated person in Cvent. From Datetime: {from_datetime}') + return mk_resp(data=None, status_code=400, response=commons.response) # Bad Request + + log.warning('Sleeping for 1 second to avoid Cvent rate limit...') + time.sleep(1.25) + + cvent_contact_list = cvent_contact_list_result.get('data') + for cvent_person_contact_obj in cvent_contact_list: + cvent_person_contact_id = cvent_person_contact_obj.get('id') + log.info(f'Processing Cvent (Person) Contact ID: {cvent_person_contact_id}') + if create_update_aether_person_result := create_update_aether_person( + cvent_contact_id = cvent_person_contact_id, + cvent_contact_obj = cvent_person_contact_obj, + account_id = account_id, + person_id = None, + ): + # person_obj = create_update_aether_person_result + person_id = create_update_aether_person_result + else: + log.info(f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') + + log.warning('Sleeping for 1 second to avoid Cvent rate limit...') + time.sleep(.75) + + return mk_resp(data=cvent_contact_list_result, status_message=f'Checked for recent changes in Cvent. Created/Updated {len(cvent_contact_list)} Cvent contacts', response=commons.response) +# ### END ### API Cvent ### get_person_recent_changes() ### + + +# ### BEGIN ### API Cvent ### get_person() ### +# Updated 2022-02-02 +@router.get('/person/{cvent_person_contact_id}', response_model=Resp_Body_Base) async def get_person( - cvent_person_id: str = Query(..., min_length=36, max_length=36), # UUID v4; actually the Cvent Contact UUID for a person + cvent_person_contact_id: str = Query(..., min_length=36, max_length=36), # UUID v4; actually the Cvent Contact UUID for a person person_id: str = Query(None, min_length=11, max_length=22), commons: Common_Route_Params = Depends(common_route_params), @@ -51,47 +99,35 @@ async def get_person( else: return mk_resp(data=None, status_code=404, response=commons.response) # ### SECTION ### Get the Cvent Contact with the Cvent UUID. - if cvent_contact_obj_result := get_contact_id(contact_id=cvent_person_id): - cvent_contact_obj = cvent_contact_obj_result + if cvent_person_contact_obj_result := get_contact_id(contact_id=cvent_person_contact_id): + cvent_person_contact_obj = cvent_person_contact_obj_result else: - log.info(f'Cvent contact not found with ID: {cvent_person_id}') + log.info(f'Cvent contact not found with ID: {cvent_person_contact_id}') return mk_resp(data=None, status_code=404, response=commons.response) # Not Found - # cvent_contact_obj = {'id': '59B1642A-E193-4B47-910B-566029C44620', 'firstName': 'Nicholas', 'lastName': 'Kasnick', 'email': 'kasnick6412@gmail.com', 'homePhone': '3603494072', 'homeAddress': {'address1': '14924 89th ave', 'city': 'Yelm', 'postalCode': '98597', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00293862', 'deleted': False, 'type': {'id': '03622AEE-F586-4AE5-A191-B8372543A8C8', 'name': 'Student Member'}, 'created': '2022-01-25T02:43:17.157Z', 'lastModified': '2022-01-26T16:07:43.505Z', 'createdBy': 'kasnick6412@gmail.com', 'lastModifiedBy': 'kasnick6412@gmail.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-24', 'expiration': '2023-01-24'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Male'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['Student, Qualifying Healthcare Professional'], 'type': 'SingleSelect', 'order': 3}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['In Training'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'Al-Anon'], 'type': 'MultiSelect', 'order': 7}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['2022-01-08T00:00'], 'type': 'Date', 'order': 22}]} + # cvent_person_contact_obj = {'id': '59B1642A-E193-4B47-910B-566029C44620', 'firstName': 'Nicholas', 'lastName': 'Kasnick', 'email': 'kasnick6412@gmail.com', 'homePhone': '3603494072', 'homeAddress': {'address1': '14924 89th ave', 'city': 'Yelm', 'postalCode': '98597', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00293862', 'deleted': False, 'type': {'id': '03622AEE-F586-4AE5-A191-B8372543A8C8', 'name': 'Student Member'}, 'created': '2022-01-25T02:43:17.157Z', 'lastModified': '2022-01-26T16:07:43.505Z', 'createdBy': 'kasnick6412@gmail.com', 'lastModifiedBy': 'kasnick6412@gmail.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-24', 'expiration': '2023-01-24'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Male'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['Student, Qualifying Healthcare Professional'], 'type': 'SingleSelect', 'order': 3}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['In Training'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'Al-Anon'], 'type': 'MultiSelect', 'order': 7}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['2022-01-08T00:00'], 'type': 'Date', 'order': 22}]} - # cvent_contact_obj = {'id': 'C5D6EBB7-8CDE-492E-A953-5243942CB66E', 'firstName': 'C Eve J', 'lastName': 'Kimball', 'email': 'doceve1@gmail.com', 'prefix': 'Dr.', 'homePhone': '6104638775', 'homeAddress': {'address1': '14 GAELSONG LN', 'city': 'WYOMISSING', 'region': 'Pennsylvania', 'regionCode': 'PA', 'postalCode': '19610', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00037205', 'deleted': False, 'type': {'id': 'A01900AB-496A-48A1-9B04-C2874651227E', 'name': 'Member'}, 'created': '2022-01-29T14:00:36.103Z', 'lastModified': '2022-01-31T18:36:34.809Z', 'createdBy': 'doceve1@gmail.com', 'lastModifiedBy': 'doceve1@gmail.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-29', 'expiration': '2023-01-29'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Female'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['M.D.'], 'type': 'SingleSelect', 'order': 3}, {'id': 'd6c6eb81-b08f-4970-9853-2fbb799d9bd1', 'name': 'Professional Designations', 'value': ['MD'], 'type': 'FreeText', 'order': 4}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['Retired'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c33feaa8-a135-48b3-96c5-d6b46f894a06', 'name': 'Practice Specialty', 'value': ['Pediatrics'], 'type': 'SingleSelect', 'order': 6}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'Al-Anon', 'OA'], 'type': 'MultiSelect', 'order': 7}, {'id': '90ec10c2-59c9-47bd-8c2f-fc253da4975c', 'name': 'Emergency Contact', 'value': ['Dan Kimball - 610-406-7753'], 'type': 'FreeText', 'order': 8}, {'id': 'd0b462b8-b9f3-420d-836c-6c0c75dcbe12', 'name': 'SO Name Prefix', 'value': ['Dr.'], 'type': 'FreeText', 'order': 9}, {'id': '59284f29-b089-4e49-b980-795861514798', 'name': 'SO First Name', 'value': ['Daniel B'], 'type': 'FreeText', 'order': 10}, {'id': '65235cc9-5b66-48d4-a7d5-8a8d3f22872a', 'name': 'SO Last Name', 'value': ['Kimball, Jr.'], 'type': 'FreeText', 'order': 11}, {'id': '50d5efaa-d629-4eeb-8d6e-f51b95eb2eb9', 'name': 'SO Professional Designation', 'value': ['MD'], 'type': 'FreeText', 'order': 12}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['1979-03-31T00:00'], 'type': 'Date', 'order': 22}]} + # cvent_person_contact_obj = {'id': 'C5D6EBB7-8CDE-492E-A953-5243942CB66E', 'firstName': 'C Eve J', 'lastName': 'Kimball', 'email': 'doceve1@gmail.com', 'prefix': 'Dr.', 'homePhone': '6104638775', 'homeAddress': {'address1': '14 GAELSONG LN', 'city': 'WYOMISSING', 'region': 'Pennsylvania', 'regionCode': 'PA', 'postalCode': '19610', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00037205', 'deleted': False, 'type': {'id': 'A01900AB-496A-48A1-9B04-C2874651227E', 'name': 'Member'}, 'created': '2022-01-29T14:00:36.103Z', 'lastModified': '2022-01-31T18:36:34.809Z', 'createdBy': 'doceve1@gmail.com', 'lastModifiedBy': 'doceve1@gmail.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-29', 'expiration': '2023-01-29'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Female'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['M.D.'], 'type': 'SingleSelect', 'order': 3}, {'id': 'd6c6eb81-b08f-4970-9853-2fbb799d9bd1', 'name': 'Professional Designations', 'value': ['MD'], 'type': 'FreeText', 'order': 4}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['Retired'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c33feaa8-a135-48b3-96c5-d6b46f894a06', 'name': 'Practice Specialty', 'value': ['Pediatrics'], 'type': 'SingleSelect', 'order': 6}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'Al-Anon', 'OA'], 'type': 'MultiSelect', 'order': 7}, {'id': '90ec10c2-59c9-47bd-8c2f-fc253da4975c', 'name': 'Emergency Contact', 'value': ['Dan Kimball - 610-406-7753'], 'type': 'FreeText', 'order': 8}, {'id': 'd0b462b8-b9f3-420d-836c-6c0c75dcbe12', 'name': 'SO Name Prefix', 'value': ['Dr.'], 'type': 'FreeText', 'order': 9}, {'id': '59284f29-b089-4e49-b980-795861514798', 'name': 'SO First Name', 'value': ['Daniel B'], 'type': 'FreeText', 'order': 10}, {'id': '65235cc9-5b66-48d4-a7d5-8a8d3f22872a', 'name': 'SO Last Name', 'value': ['Kimball, Jr.'], 'type': 'FreeText', 'order': 11}, {'id': '50d5efaa-d629-4eeb-8d6e-f51b95eb2eb9', 'name': 'SO Professional Designation', 'value': ['MD'], 'type': 'FreeText', 'order': 12}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['1979-03-31T00:00'], 'type': 'Date', 'order': 22}]} - # cvent_contact_obj = {'id': 'E1DB2588-8CFA-439B-82E7-63F65BA9CE90', 'firstName': 'Edward', 'lastName': 'Breslow', 'email': 'ed.breslow@yahoo.com', 'homePhone': '4344268975', 'homeAddress': {'address1': '10566 Ratcliffe Trail', 'city': 'Manassas', 'region': 'Virginia', 'regionCode': 'VA', 'postalCode': '20110', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00010745', 'deleted': False, 'type': {'id': 'A01900AB-496A-48A1-9B04-C2874651227E', 'name': 'Member'}, 'created': '2022-01-24T16:43:38.307Z', 'lastModified': '2022-02-01T15:06:55.540Z', 'createdBy': 'ed.breslow@yahoo.com', 'lastModifiedBy': 'ed.breslow@yahoo.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-24', 'expiration': '2023-01-24'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Male'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['R.Ph.'], 'type': 'SingleSelect', 'order': 3}, {'id': 'd6c6eb81-b08f-4970-9853-2fbb799d9bd1', 'name': 'Professional Designations', 'value': ['Rph'], 'type': 'FreeText', 'order': 4}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['Active'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c33feaa8-a135-48b3-96c5-d6b46f894a06', 'name': 'Practice Specialty', 'value': ['Pharmacology, Doctorate'], 'type': 'SingleSelect', 'order': 6}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'NA'], 'type': 'MultiSelect', 'order': 7}, {'id': '90ec10c2-59c9-47bd-8c2f-fc253da4975c', 'name': 'Emergency Contact', 'value': ['Jamie Long 434-386-1144'], 'type': 'FreeText', 'order': 8}, {'id': 'd0b462b8-b9f3-420d-836c-6c0c75dcbe12', 'name': 'SO Name Prefix', 'value': ['Mrs'], 'type': 'FreeText', 'order': 9}, {'id': '59284f29-b089-4e49-b980-795861514798', 'name': 'SO First Name', 'value': ['Edward'], 'type': 'FreeText', 'order': 10}, {'id': '65235cc9-5b66-48d4-a7d5-8a8d3f22872a', 'name': 'SO Last Name', 'value': ['Breslow'], 'type': 'FreeText', 'order': 11}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['2021-10-15T00:00'], 'type': 'Date', 'order': 22}]} + # cvent_person_contact_obj = {'id': 'E1DB2588-8CFA-439B-82E7-63F65BA9CE90', 'firstName': 'Edward', 'lastName': 'Breslow', 'email': 'ed.breslow@yahoo.com', 'homePhone': '4344268975', 'homeAddress': {'address1': '10566 Ratcliffe Trail', 'city': 'Manassas', 'region': 'Virginia', 'regionCode': 'VA', 'postalCode': '20110', 'country': 'USA', 'countryCode': 'US'}, 'sourceId': '00010745', 'deleted': False, 'type': {'id': 'A01900AB-496A-48A1-9B04-C2874651227E', 'name': 'Member'}, 'created': '2022-01-24T16:43:38.307Z', 'lastModified': '2022-02-01T15:06:55.540Z', 'createdBy': 'ed.breslow@yahoo.com', 'lastModifiedBy': 'ed.breslow@yahoo.com', 'optOut': {'optedOut': False, 'by': 'Cvent Support'}, 'membership': {'joined': '2022-01-24', 'expiration': '2023-01-24'}, 'customFields': [{'id': 'e46d8043-705b-4315-9611-6fba9211b2e2', 'name': 'Non-Binary Gender', 'value': ['Male'], 'type': 'SingleSelect', 'order': 2}, {'id': '656b419b-d974-49a7-85df-cda564a7a06e', 'name': 'Qualifying Degree', 'value': ['R.Ph.'], 'type': 'SingleSelect', 'order': 3}, {'id': 'd6c6eb81-b08f-4970-9853-2fbb799d9bd1', 'name': 'Professional Designations', 'value': ['Rph'], 'type': 'FreeText', 'order': 4}, {'id': '1ef02428-59a1-493a-8535-407ed5d65f6f', 'name': 'Practice Status', 'value': ['Active'], 'type': 'SingleSelect', 'order': 5}, {'id': 'c33feaa8-a135-48b3-96c5-d6b46f894a06', 'name': 'Practice Specialty', 'value': ['Pharmacology, Doctorate'], 'type': 'SingleSelect', 'order': 6}, {'id': 'c1b47d46-d219-4f1a-a8f9-8030c7f55f31', 'name': 'Recovery Programs', 'value': ['AA', 'NA'], 'type': 'MultiSelect', 'order': 7}, {'id': '90ec10c2-59c9-47bd-8c2f-fc253da4975c', 'name': 'Emergency Contact', 'value': ['Jamie Long 434-386-1144'], 'type': 'FreeText', 'order': 8}, {'id': 'd0b462b8-b9f3-420d-836c-6c0c75dcbe12', 'name': 'SO Name Prefix', 'value': ['Mrs'], 'type': 'FreeText', 'order': 9}, {'id': '59284f29-b089-4e49-b980-795861514798', 'name': 'SO First Name', 'value': ['Edward'], 'type': 'FreeText', 'order': 10}, {'id': '65235cc9-5b66-48d4-a7d5-8a8d3f22872a', 'name': 'SO Last Name', 'value': ['Breslow'], 'type': 'FreeText', 'order': 11}, {'id': '84210a3a-43c9-491d-badf-fd5bb19151b7', 'name': 'Paper Mail Opted Out', 'value': ['Yes'], 'type': 'SingleSelect', 'order': 17}, {'id': '3b91172f-3cde-4ffc-822e-6bcc80a1eda7', 'name': 'I am joining IDAA as a', 'value': ['Medical member with a qualifying degree'], 'type': 'SingleSelect', 'order': 21}, {'id': '2245946b-2634-4044-8ad5-3cd897424f32', 'name': 'Sobriety Date', 'value': ['2021-10-15T00:00'], 'type': 'Date', 'order': 22}]} - - # log.debug(json.dumps(cvent_contact_obj, indent=2, default=str)) + # log.debug(json.dumps(cvent_person_contact_obj, indent=2, default=str)) # Important variables used more than once. account_id = commons.x_account_id - # person_external_id = None - # if custom_field_list := cvent_contact_obj.get('customFields'): # List - # for custom_field in custom_field_list: - # # Get the External ID created by OSIT - # if custom_field.get('id') == '609ab766-7d79-4a9d-a72c-f126412659ee': - # # person_data['external_id'] = custom_field.get('value')[0] - # person_external_id = custom_field.get('value')[0] - # email = cvent_contact_obj.get('email') - # membership_person_id = None - # membership_person_type_id = None if create_update_aether_person_result := create_update_aether_person( - cvent_contact_id = cvent_person_id, - cvent_contact_obj = cvent_contact_obj, + cvent_contact_id = cvent_person_contact_id, + cvent_contact_obj = cvent_person_contact_obj, account_id = account_id, person_id = person_id ): person_obj = create_update_aether_person_result return mk_resp(data=person_obj, status_message='Created/Updated and loaded person based on Cvent contact information', response=commons.response) else: - log.info(f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_id}') + log.info(f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') return mk_resp(data=None, status_code=400, response=commons.response) # Bad Request - # Important contact fields: # id (UUID v4) # type { id, name } for contact type (membership type) @@ -110,81 +146,6 @@ async def get_person( # workPhone # homeAddress { address1, address2, address3, city, country, countryCode, postalCode, region, regionCode } - person_data = {} - person_data['external_id'] = person_external_id - # person_data['pronouns'] = ??? - person_data['informal_name'] = cvent_contact_obj.get('nickname') - person_data['title_names'] = cvent_contact_obj.get('prefix') - person_data['given_name'] = cvent_contact_obj.get('firstName') - person_data['middle_name'] = cvent_contact_obj.get('middleName') - person_data['family_name'] = cvent_contact_obj.get('lastName') - person_data['designations'] = cvent_contact_obj.get('designation') - person_data['professional_title'] = cvent_contact_obj.get('title') - person_data['affiliations'] = cvent_contact_obj.get('company') - person_data['enable'] = True - log.debug(person_data) - - contact_data = {} - contact_data['email'] = cvent_contact_obj.get('email') - contact_data['cc_email'] = cvent_contact_obj.get('ccEmail') - contact_data['phone_mobile'] = cvent_contact_obj.get('mobilePhone') - contact_data['phone_home'] = cvent_contact_obj.get('homePhone') - contact_data['phone_office'] = cvent_contact_obj.get('workPhone') - log.debug(contact_data) - - address_data = {} - if cvent_contact_obj.get('homeAddress'): - address_data['line_1'] = cvent_contact_obj.get('homeAddress').get('address1') - address_data['line_2'] = cvent_contact_obj.get('homeAddress').get('address2') - address_data['line_3'] = cvent_contact_obj.get('homeAddress').get('address3') - address_data['city'] = cvent_contact_obj.get('homeAddress').get('city') - address_data['state_province'] = cvent_contact_obj.get('homeAddress').get('region') - if cvent_contact_obj.get('homeAddress').get('countryCode') and cvent_contact_obj.get('homeAddress').get('regionCode'): - country_subdivision_code = cvent_contact_obj.get('homeAddress').get('countryCode') +'-'+ cvent_contact_obj.get('homeAddress').get('regionCode') - address_data['country_subdivision_code'] = country_subdivision_code - address_data['postal_code'] = cvent_contact_obj.get('homeAddress').get('postalCode') - address_data['country_alpha_2_code'] = cvent_contact_obj.get('homeAddress').get('countryCode') - address_data['country'] = cvent_contact_obj.get('homeAddress').get('country') - address_data['country_alpha_2_code'] = cvent_contact_obj.get('homeAddress').get('countryCode') - log.debug(address_data) - contact_data['address'] = address_data - person_data['contact'] = contact_data - - user_data = {} - # user_data['name'] = - user_data['username'] = cvent_contact_obj.get('email') - user_data['email'] = cvent_contact_obj.get('email') - random_password_string = secrets.token_urlsafe(8) - user_data['password'] = secure_hash_string(string=random_password_string) - - user_data['email_verified'] = True # Assuming this is True because they came from another system where the email address is required. - - user_data['enable'] = True - user_data['enable_from'] = datetime.datetime.now(datetime.timezone.utc) - user_data['enable_to'] = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365) - - user_data['super'] = False # This is just not allowed - user_data['manager'] = False # This is just not allowed - # user_data['administrator'] = False - - user_data['public'] = False - user_data['verified'] = True - user_data['notes'] = 'Created by importing list' - - other_data = {} - other_data['temp_password'] = random_password_string - user_data['other_json'] = json.dumps(other_data, indent=4) - person_data['user'] = user_data - - # membership_person_data = {} - # membership_person_data['first_start_on'] = cvent_contact_obj.get('membership').get('joined') # A trigger should update 'first_start_on' if needed??? - # membership_person_data['start_on'] = cvent_contact_obj.get('membership').get('lastRenewal') # A trigger should update 'first_start_on' if needed??? - # membership_person_data['end_on'] = cvent_contact_obj.get('membership').get('expiration') - # log.debug(json.dumps(membership_person_data, indent=2, default=str)) - - membership_type_cvent_id = cvent_contact_obj.get('type').get('id') - membership_type_cvent_name = cvent_contact_obj.get('type').get('name') - log.info(f'Found Cvent Membership Type Named: {membership_type_cvent_name}') # 'id': '5EB898D8-C253-482C-A93A-0B6667C26E04', 'name': 'Al-Anon Member' # 'id': 'A20358C5-0F6C-47AF-9843-BA9483A9D767', 'name': 'Al-Anon Non-Member' # 'id': 'A01900AB-496A-48A1-9B04-C2874651227E', 'name': 'Member' @@ -200,197 +161,143 @@ async def get_person( # 'id': '71D07118-C24D-4B2E-888D-56AC1B941495', 'name': "IDAA 20's Guest Registration" # 'id': 'DA17F721-9924-43E3-A31F-C567BA96DC64', 'name': 'IDAA Teen (13-19 years)' # 'id': 'C49439B3-5AE6-496F-A0AD-4CCB1A9000E3', 'name': 'Spouse/SO Guest Registration' - - # Currently in use for IDAA: - # Member Type = Member Contact Type - # Annual Contribution(s) = Attendee - # Doctoral Qualifying Member(s) = Member - # Student Member(s) = Student Member - - membership_person_data = {} - membership_person_type_data = {} - if membership_type_cvent_name == 'Al-Anon Member' or membership_type_cvent_name == 'Al-Anon Members': - # membership_person_data['membership_type_id'] = 6 - membership_person_type_data['membership_type_id'] = 6 - membership_person_type_data['product_id'] = 13 - # membership_person_data['level'] = 1 - membership_person_type_data['level'] = 1 - elif membership_type_cvent_name == 'Annual Contribution' or membership_type_cvent_name == 'Annual Contributions' or membership_type_cvent_name == 'Attendee': # Unsure... making affiliate - # membership_person_data['membership_type_id'] = 8 - membership_person_type_data['membership_type_id'] = 8 - membership_person_type_data['product_id'] = 13 - # membership_person_data['level'] = 3 - membership_person_type_data['level'] = 3 - elif membership_type_cvent_name == 'Doctoral Qualifying Member' or membership_type_cvent_name == 'Doctoral Qualifying Members' or membership_type_cvent_name == 'Member': - # membership_person_data['membership_type_id'] = 5 - membership_person_type_data['membership_type_id'] = 5 - membership_person_type_data['product_id'] = 4 - # membership_person_data['level'] = 1 - membership_person_type_data['level'] = 1 - elif membership_type_cvent_name == 'Student Member' or membership_type_cvent_name == 'Student Members': - # membership_person_data['membership_type_id'] = 7 - membership_person_type_data['membership_type_id'] = 7 - membership_person_type_data['product_id'] = 14 - # membership_person_data['level'] = 1 - membership_person_type_data['level'] = 1 - else: - log.error(f'Unknown Membership Type Name from Cvent: {membership_type_cvent_name}') - return mk_resp(data=person_data, status_code=400, response=commons.response, status_message='The membership type name from Cvent was unknown.') # Bad Request - - membership_person_type_data['first_start_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('joined'), '%Y-%m-%d') - if cvent_contact_obj.get('membership').get('lastRenewal'): - membership_person_type_data['start_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('lastRenewal'), '%Y-%m-%d') - else: - membership_person_type_data['start_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('joined'), '%Y-%m-%d') - membership_person_type_data['end_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('expiration'), '%Y-%m-%d') - membership_person_type_data['last_end_on'] = datetime.datetime.strptime(cvent_contact_obj.get('membership').get('expiration'), '%Y-%m-%d') - - current_datetime = datetime.datetime.now() - if membership_person_type_data['end_on'] >= current_datetime: - membership_person_type_data['lu_membership_type_status_id'] = 5 # 5 = active; expiration is > now - else: - membership_person_type_data['lu_membership_type_status_id'] = 7 # 7 = inactive; expiration is < now - - membership_person_data['enable'] = True - membership_person_type_data['enable'] = True - - membership_person_data['membership_person_type'] = membership_person_type_data - log.debug(json.dumps(membership_person_data, indent=2, default=str)) - - # ### TESTING BREAK POINT ### - # person_data['membership_person'] = membership_person_data - # return mk_resp(data=person_data, status_code=501, response=commons.response, status_message='Testing...') - # ### TESTING BREAK POINT ### - - # Try to look up using external ID - if not person_id and person_external_id: - log.info(f'Looking up person with External ID: {person_external_id}') - if result := get_person_rec_w_external_id(account_id=account_id, external_id=person_external_id): - log.debug(result) - person_id = result.get('person_id') - log.info(f'Person ID {person_id} found using external ID.') - else: pass - # If that fails then try to look up using email address - if not person_id and email: - log.info(f'Looking up person with Email Address: {email}') - if result := get_person_rec_list(for_obj_type='account', for_obj_id=account_id, email=email): - log.debug(result[0]) - person_id = result[0].get('person_id') - log.info(f'Person ID {person_id} found using email address.') - else: pass - log.debug(f'Person ID: {person_id}; External ID: {person_external_id}; Email: {email}') - - - # ### TESTING BREAK POINT ### - # person_data['membership_person'] = membership_person_data - # return mk_resp(data=person_data, status_code=501, response=commons.response, status_message='Testing...') - # ### TESTING BREAK POINT ### - - - # If there is not an external ID for an existing or new person then one needs to be created. - if not person_external_id: - N = 8 - random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=N)) - random_string = ''.join(random.SystemRandom().choices(string.ascii_uppercase + string.digits, k=N)) - # random_string = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N)) - log.info(f'Created random string: {random_string}') - - email = cvent_contact_obj.get('email') - - person_external_id = f'{random_string}~{email}' - log.info(f'Created new Person External ID: {person_external_id}') - person_data['external_id'] = person_external_id - - # NOTE: Update Cvent Contact - custom_field_id = '609ab766-7d79-4a9d-a72c-f126412659ee' # IDAA Cvent External ID UUID - custom_field_value = [person_external_id] - - log.warning('Sleeping for 1 second to avoid Cvent rate limit...') - time.sleep(1) - - contact_mod_result = modify_contact_id( - contact_id = cvent_person_id, # This is the Cvent Contact UUID for a person - # field_list = field_list, - custom_field_id = custom_field_id, - custom_field_value = custom_field_value, - ) - - if person_id: - # ### SECTION ### Load person object to populate the person_data and membership_person_data dicts. - person_obj = load_person_obj(person_id=person_id, inc_address=True, inc_contact=True, inc_membership_person=True, inc_membership_person_type=True, inc_user=True) - log.debug(person_obj) - - person_data['id'] = person_id - person_data['account_id'] = account_id - person_data['contact']['id'] = person_obj.contact.id - person_data['contact']['address']['id'] = person_obj.contact.address.id - if person_obj.user: - person_data['user']['id'] = person_obj.user.id - - if person_obj.membership_person: - membership_person_id = person_obj.membership_person.id - if person_obj.membership_person.membership_person_type: - membership_person_type_id = person_obj.membership_person.membership_person_type.id - - if not person_obj.external_id: - person_data['external_id'] = person_external_id - log.debug(person_data) - if update_person_kiss(person_id=person_id, person_dict_obj=person_data): - log.info(f'Updated Person ID: {person_id}') - else: - log.info(f'Did not update Person ID: {person_id}') - else: - # ### SECTION ### Create new person and related with the person_data and membership_person_data dicts. - - # person_data['id'] = person_id - person_data['account_id'] = account_id - # person_data['contact']['id'] = person_obj.contact.id - # person_data['contact']['address']['id'] = person_obj.contact.address.id - # person_data['user']['id'] = person_obj.user.id - log.debug(person_data) - if create_person_obj_result := create_person_kiss(account_id=account_id, person_dict_obj=person_data): - person_id = create_person_obj_result - log.info(f'Created Person ID: {person_id}') - else: - log.info(f'Did not create Person') - - - # ### TESTING BREAK POINT ### - # person_data['membership_person'] = membership_person_data - # return mk_resp(data=person_data, status_code=501, response=commons.response, status_message='Testing...') - # ### TESTING BREAK POINT ### - - - if membership_person_id: - # membership_person_id = person_obj.membership_person.id - membership_person_data['id'] = membership_person_id - membership_person_data['membership_person_type']['id'] = membership_person_type_id - if update_membership_person_obj(membership_person_id=membership_person_id, membership_person_dict_obj=membership_person_data): - log.info(f'Updated Membership Person ID: {membership_person_id}') - else: - log.info(f'Did not update Membership Person ID: {membership_person_id}') - - # person_data['membership_person'] = membership_person_data - - # return mk_resp(data=person_data, status_message='Updated and loaded person based on Cvent contact information', response=commons.response) - else: - # membership_person_id = person_obj.membership_person.id - # membership_person_data['id'] = person_obj.membership_person.id - # membership_person_data['membership_person_type']['id'] = person_obj.membership_person.membership_person_type.id - # membership_person_data['person_id'] = person_id - if create_membership_person_obj_result := create_membership_person_obj(account_id=account_id, person_id=person_id, membership_person_dict_obj=membership_person_data): - membership_person_id = create_membership_person_obj_result - log.info(f'Created Membership Person ID: {membership_person_id}') - else: - log.info(f'Did not create Membership Person') - - person_data['membership_person'] = membership_person_data - log.debug(json.dumps(person_data, indent=2, default=str)) - - person_obj = load_person_obj(person_id=person_id, inc_address=True, inc_contact=True, inc_membership_person=True, inc_membership_person_type=True, inc_user=True) - log.debug(person_obj) - - return mk_resp(data=person_obj, status_message='Created/Updated and loaded person based on Cvent contact information', response=commons.response) - - # return mk_resp(data=person_data, status_message='Got Cvent contact information', response=commons.response) # ### END ### API Cvent ### get_person() ### + + +# ### BEGIN ### API Cvent ### get_person_w_email() ### +# Updated 2022-02-02 +@router.get('/person/email/{email}', response_model=Resp_Body_Base) +async def get_person_w_email( + email: str = Query(..., min_length=5, max_length=75), + person_id: str = Query(None, min_length=11, max_length=22), + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + if person_id := redis_lookup_id_random(record_id_random=person_id, table_name='person'): pass + elif person_id is None: pass + else: return mk_resp(data=None, status_code=404, response=commons.response) + + account_id = commons.x_account_id + + # ### SECTION ### Get the Cvent Contact with the email address. There should only be zero or one results. + if cvent_person_contact_list_result := get_contact_list(email=email): + log.debug(cvent_person_contact_list_result) + # cvent_person_contact_list = cvent_person_contact_list_result + else: + log.info(f'Cvent contact not found with Email: {email}') + return mk_resp(data=None, status_code=404, response=commons.response) # Not Found + + cvent_contact_list = cvent_person_contact_list_result.get('data') + log.debug(json.dumps(cvent_contact_list, indent=2, default=str)) + if len(cvent_contact_list) == 1: + cvent_person_contact_obj = cvent_contact_list[0] + cvent_person_contact_id = cvent_person_contact_obj.get('id') + log.info(f'Processing Cvent (Person) Contact ID: {cvent_person_contact_id}') + if create_update_aether_person_result := create_update_aether_person( + cvent_contact_id = cvent_person_contact_id, + cvent_contact_obj = cvent_person_contact_obj, + account_id = account_id, + person_id = person_id, + ): + # person_obj = create_update_aether_person_result + person_id = create_update_aether_person_result + # return mk_resp(data=person_obj, status_message=f'Checked for recent changes in Cvent. Created/Updated {len(cvent_contact_list)} Cvent contacts', response=commons.response) + else: + log.info(f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') + return mk_resp(data=None, status_code=400, response=commons.response,status_message=f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') # Bad Request + else: + log.info(f'More than one result was returned with the email address. Email Address: {email}') + return mk_resp(data=None, status_code=400, response=commons.response) # Bad Request + + # ### SECTION ### Return successful results + if return_obj: + person_obj = load_person_obj( + person_id = person_id, + inc_address = inc_address, + inc_contact = inc_contact, + # inc_organization = inc_organization, + inc_user = inc_user, + inc_user_role_list = inc_user_role_list, + ).dict(by_alias=commons.by_alias, exclude_unset=commons.exclude_unset) + data = person_obj + else: + data = {} + data['person_id'] = person_id + data['person_id_random'] = person_id_random + return mk_resp(data=data, response=commons.response) +# ### END ### API Cvent ### get_person_w_email() ### + + +# ### BEGIN ### API Cvent ### get_person_w_external_id() ### +# Updated 2022-02-02 +@router.get('/person/external_id/{external_id}', response_model=Resp_Body_Base) +async def get_person_w_external_id( + external_id: str = Query(..., min_length=10, max_length=100), + person_id: str = Query(None, min_length=11, max_length=22), + + inc_address: bool = False, + inc_contact: bool = False, + inc_user: bool = False, + inc_user_role_list: bool = False, + return_obj: Optional[bool] = True, + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + if person_id := redis_lookup_id_random(record_id_random=person_id, table_name='person'): pass + elif person_id is None: pass + else: return mk_resp(data=None, status_code=404, response=commons.response) + + account_id = commons.x_account_id + + # ### SECTION ### Get the Cvent Contact with the external ID. There should only be zero or one results. + if cvent_person_contact_list_result := get_contact_list(external_id=external_id): + log.debug(cvent_person_contact_list_result) + # cvent_person_contact_list = cvent_person_contact_list_result + else: + log.info(f'Cvent contact not found with External ID: {external_id}') + return mk_resp(data=None, status_code=404, response=commons.response) # Not Found + + cvent_contact_list = cvent_person_contact_list_result.get('data') + if len(cvent_contact_list) == 1: + cvent_person_contact_obj = cvent_contact_list[0] + cvent_person_contact_id = cvent_person_contact_obj.get('id') + log.info(f'Processing Cvent (Person) Contact ID: {cvent_person_contact_id}') + if create_update_aether_person_result := create_update_aether_person( + cvent_contact_id = cvent_person_contact_id, + cvent_contact_obj = cvent_person_contact_obj, + account_id = account_id, + person_id = person_id, + ): + # person_obj = create_update_aether_person_result + person_id = create_update_aether_person_result + # return mk_resp(data=person_obj, status_message=f'Checked for recent changes in Cvent. Created/Updated {len(cvent_contact_list)} Cvent contacts', response=commons.response) + else: + log.info(f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') + return mk_resp(data=None, status_code=400, response=commons.response,status_message=f'Something went wrong while trying to create or update the person in Aether based on Cvent data. Cvent (Person) Contact ID: {cvent_person_contact_id}') # Bad Request + else: + log.info(f'More than one result was returned with the external ID. External ID: {email}') + return mk_resp(data=None, status_code=400, response=commons.response) # Bad Request + + # ### SECTION ### Return successful results + if return_obj: + person_obj = load_person_obj( + person_id = person_id, + inc_address = inc_address, + inc_contact = inc_contact, + # inc_organization = inc_organization, + inc_user = inc_user, + inc_user_role_list = inc_user_role_list, + ).dict(by_alias=commons.by_alias, exclude_unset=commons.exclude_unset) + data = person_obj + else: + data = {} + data['person_id'] = person_id + data['person_id_random'] = person_id_random + return mk_resp(data=data, response=commons.response) +# ### END ### API Cvent ### get_person_w_external_id() ### \ No newline at end of file