Cleaning up create and update Cvent person in Aether for IDAA members. Added lookup by external ID and email for Cvent.

This commit is contained in:
Scott Idem
2022-02-02 18:16:58 -05:00
parent 2f4152ff8b
commit d8065efec5
3 changed files with 271 additions and 344 deletions

View File

@@ -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() ###

View File

@@ -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)

View File

@@ -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() ###