Working on Cvent API for IDAA members. Adding and updating a person along with membership info now works. Updating the membership status for person and user tables now works.

This commit is contained in:
Scott Idem
2022-02-01 19:32:10 -05:00
parent fe3cea131a
commit 217530fb93
8 changed files with 247 additions and 42 deletions

View File

@@ -285,8 +285,8 @@ def sql_update(
else:
log.debug(result_update)
log.debug(f'rowcount = {result_update.rowcount}; lastrowid = {result_update.lastrowid}')
if result_update.rowcount == 1 and result_update.lastrowid == 0: # update with no change
log.info('Update record (with no change???)') # With SQL UPDATE this record may have actually changed
if result_update.rowcount >= 1 and result_update.lastrowid == 0: # update with no change
log.info(f'Updated {result_update.rowcount} records (with no changes?)') # With SQL UPDATE this record may have actually changed
return True
elif result_update.rowcount == 2 and result_update.lastrowid > 0: # update with change
log.warning('Should we be here???')
@@ -625,11 +625,10 @@ def sql_select(
return False # Not successful
else:
log.info('Successfully executed the SQL on the first try.')
log.debug('Successfully executed the SQL on the first try.')
pass
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.info(f'Row count: {result.rowcount}')
log.debug(f'Row count: {result.rowcount}')
#log.debug(vars(result))
#log.debug(dir(result))
if result.rowcount == 1:

View File

@@ -18,7 +18,7 @@ from . import config
from app.log import log, logging
# Import the routers here first:
from app.routers import api_crud, api, importing, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, event, event_badge, event_badge_template, event_exhibit, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, site, site_domain, user, websockets, e_cvent#, e_impexium
from app.routers import api_crud, api, importing, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, event, event_badge, event_badge_template, event_exhibit, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, site, site_domain, user, websockets, e_cvent, c_idaa #, e_impexium
from app.db_sql import db
@@ -327,6 +327,12 @@ app.include_router(
# tags=['External Service: Impexium'],
# )
app.include_router(
c_idaa.router,
prefix='/c/idaa',
tags=['Client: IDAA'],
)
# BEGIN: CORS
origins = [

View File

@@ -1,12 +1,12 @@
from __future__ import annotations
import datetime, pprint, pytz, random, requests
import datetime, pprint, pytz, random, requests, time
from requests.auth import HTTPBasicAuth
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from app.db_sql import redis_lookup_id_random, sql_insert, sql_select, sql_update
from app.lib_general import log, logging
from app.lib_general import log, logging, logger_reset
from app.methods.person_methods import get_person_rec_w_external_id, load_person_obj, update_person_kiss
@@ -20,9 +20,10 @@ api['base_url'] = 'https://api-platform.cvent.com/ea' # Including /ea as the Cve
api['headers'] = {} # { 'Content-Type': content_type, 'Authorization': 'Basic '+str(cvent_authorization_base64) }
# def get_access_token(api, app):
# Updated 2022-02-01
@logger_reset
def get_access_token():
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
log.debug(f'API data:\n{api}')
@@ -85,6 +86,8 @@ def get_access_token():
return api
# Updated 2022-01-31
@logger_reset
def get_contact_custom_field_list(api):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
@@ -110,7 +113,9 @@ def get_contact_custom_field_list(api):
return response_data
def get_contact_list(api, external_id=False):
# Updated 2022-01-31
@logger_reset
def get_contact_list(api, external_id: str=False):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
@@ -140,8 +145,9 @@ def get_contact_list(api, external_id=False):
return response_data
# def get_contact_id(api, contact_id):
def get_contact_id(contact_id):
# Updated 2022-02-01
@logger_reset
def get_contact_id(contact_id: str):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
@@ -149,6 +155,9 @@ def get_contact_id(contact_id):
# else: get_access_token()
get_access_token()
log.warning('Sleeping for 1 second to avoid Cvent rate limit...')
time.sleep(1)
endpoint = f'/contacts/{contact_id}'
uri = api['base_url']+endpoint
@@ -167,3 +176,43 @@ def get_contact_id(contact_id):
# f.write(pprint.pformat(response_data, indent=2, width=160))
return response_data
# Updated 2022-02-01
@logger_reset
def modify_contact_id(contact_id: str, field_list: list=[], custom_field_id: str=None, custom_field_value: str=None):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
get_access_token()
if custom_field_id:
endpoint = f'/contacts/{contact_id}/custom-fields/{custom_field_id}/answers'
elif field_list:
endpoint = f'/contacts/{contact_id}'
else:
log.error('Missing required parameters')
return False
uri = api['base_url']+endpoint
params = {}
data = {}
if custom_field_id:
data['id'] = custom_field_id
data['value'] = custom_field_value
else:
data = field_list
data['id'] = contact_id
if custom_field_id:
resp = requests.put(url=uri, headers=api['headers'], params=params, json=data)
else:
resp = requests.patch(url=uri, headers=api['headers'], params=params, json=data)
response_data = resp.json()
log.debug(response_data)
if 'message' in response_data and response_data['message'] == 'Too Many Requests': return False
return response_data

View File

@@ -4,7 +4,7 @@ import datetime, json
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from app.lib_general import log, logging
from app.lib_general import log, logging, logger_reset
from app.db_sql import redis_lookup_id_random, sql_insert, sql_insert_or_update, sql_select, sql_update
from app.methods.membership_cfg_methods import load_membership_cfg_obj
@@ -22,6 +22,7 @@ from app.models.membership_person_models import Membership_Person_Base
# ### BEGIN ### API Membership Person Methods ### load_membership_person_obj() ###
# Updated 2022-01-11
@logger_reset
def load_membership_person_obj(
membership_person_id: int|str,
limit: int = 100,
@@ -50,7 +51,7 @@ def load_membership_person_obj(
inc_product_list: bool = False, # The list of products that give access to a member_type or member_group
# inc_user: bool = False,
) -> Membership_Person_Base:
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if membership_person_id := redis_lookup_id_random(record_id_random=membership_person_id, table_name='membership_person'): pass

View File

@@ -5,7 +5,7 @@ from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from app.db_sql import redis_lookup_id_random, sql_insert, sql_select, sql_update
from app.lib_general import log, logging
from app.lib_general import log, logging, logger_reset
# from app.methods.membership_person_methods import get_membership_person_rec_list, load_membership_person_obj
from app.methods.membership_cfg_methods import load_membership_cfg_obj
from app.methods.product_methods import get_product_rec_list, load_product_obj
@@ -16,6 +16,7 @@ from app.models.membership_person_type_models import Membership_Person_Type_Base
# ### BEGIN ### API Membership Type Person Methods ### load_membership_person_type_obj() ###
# Updated 2021-07-09
@logger_reset
def load_membership_person_type_obj(
membership_person_type_id: int|str,
limit: int = 1000,
@@ -36,7 +37,7 @@ def load_membership_person_type_obj(
inc_product_list: bool = False,
inc_person: bool = False,
) -> Membership_Person_Type_Base|bool:
# log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if membership_person_type_id := redis_lookup_id_random(record_id_random=membership_person_type_id, table_name='membership_person_type'): pass

View File

@@ -624,7 +624,7 @@ def get_person_rec_list(
limit: int = 1000,
offset: int = 0,
) -> list|bool:
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if for_obj_id := redis_lookup_id_random(record_id_random=for_obj_id, table_name=for_obj_type): pass

129
app/routers/c_idaa.py Normal file
View File

@@ -0,0 +1,129 @@
import datetime, json, pytz, random, secrets, string, time
from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, Response, status
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
from app.lib_general import log, logging, secure_hash_string, verify_secure_hash_string, common_route_params, Common_Route_Params
from app.config import settings
from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, sql_delete, redis_lookup_id_random
from app.routers.api_crud import delete_obj_template, get_obj_template, get_obj_li_template, patch_obj_template, post_obj_template
from app.models.response_models import Resp_Body_Base, mk_resp
router = APIRouter()
# ### BEGIN ### API Client: IDAA ### refresh_membership_status() ###
# Updated 2022-02-01
@router.get('/refresh_membership_status', response_model=Resp_Body_Base)
async def refresh_membership_status(
commons: Common_Route_Params = Depends(common_route_params),
):
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
sql = f"""
UPDATE user
INNER JOIN person ON user.id = person.user_id
INNER JOIN membership_person ON person.id = membership_person.person_id
SET user.email_verified = 1, user.enable = 1, user.enable_from = membership_person.start_on, user.enable_to = membership_person.end_on, user.verified = 1, user.group = 'current_member'
WHERE user.account_id = 13 AND membership_person.end_on >= NOW();
"""
if user_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(user_update_result)
else:
log.warning(f'The SQL UPDATE of user table records failed for current members')
sql = f"""
UPDATE user
INNER JOIN person ON user.id = person.user_id
INNER JOIN membership_person ON person.id = membership_person.person_id
SET user.group = 'inactive_member'
WHERE user.account_id = 13 AND membership_person.end_on < NOW() AND membership_person.end_on >= DATE(NOW() - INTERVAL 4 WEEK);
"""
if user_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(user_update_result)
else:
log.warning(f'The SQL UPDATE of user table records failed for inactive members')
sql = f"""
UPDATE user
INNER JOIN person ON user.id = person.user_id
INNER JOIN membership_person ON person.id = membership_person.person_id
SET user.group = 'suspended_member'
WHERE user.account_id = 13 AND membership_person.end_on < DATE(NOW() - INTERVAL 4 WEEK);
"""
if user_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(user_update_result)
else:
log.warning(f'The SQL UPDATE of user table records failed for suspended members')
sql = f"""
UPDATE user
INNER JOIN person ON user.id = person.user_id
LEFT JOIN membership_person ON person.id = membership_person.person_id
SET user.group = 'not_member'
WHERE user.account_id = 13 AND membership_person.id IS NULL;
"""
if user_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(user_update_result)
else:
log.warning(f'The SQL UPDATE of user table records failed for not members')
sql = f"""
UPDATE person
INNER JOIN membership_person ON person.id = membership_person.person_id
SET person.enable = 1, person.group = 'current_member'
WHERE person.account_id = 13 AND membership_person.end_on >= NOW();
"""
if person_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(person_update_result)
else:
log.warning(f'The SQL UPDATE of person table records failed for current members')
sql = f"""
UPDATE person
INNER JOIN membership_person ON person.id = membership_person.person_id
SET person.group = 'inactive_member'
WHERE person.account_id = 13 AND membership_person.end_on < NOW() AND membership_person.end_on >= DATE(NOW() - INTERVAL 4 WEEK);
"""
if person_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(person_update_result)
else:
log.warning(f'The SQL UPDATE of person table records failed for inactive members')
sql = f"""
UPDATE person
INNER JOIN membership_person ON person.id = membership_person.person_id
SET person.group = 'suspended_member'
WHERE person.account_id = 13 AND membership_person.end_on < DATE(NOW() - INTERVAL 4 WEEK);
"""
if person_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(person_update_result)
else:
log.warning(f'The SQL UPDATE of person table records failed for suspended members')
sql = f"""
UPDATE person
LEFT JOIN membership_person ON person.id = membership_person.person_id
SET person.group = 'not_member'
WHERE person.account_id = 13 AND membership_person.id IS NULL;
"""
if person_update_result := sql_update(sql=sql):
# Pull out IDs of existing person record
log.debug(person_update_result)
else:
log.warning(f'The SQL UPDATE of person table records failed for not members')
return mk_resp(data=True, status_message='Updated person and user records with current membership status', response=commons.response)
# ### END ### API Client: IDAA ### refresh_membership_status() ###

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 get_access_token, get_contact_custom_field_list, get_contact_list, get_contact_id
from app.methods.e_cvent_methods import get_access_token, get_contact_custom_field_list, get_contact_list, get_contact_id, 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
@@ -21,7 +21,7 @@ router = APIRouter()
# ### BEGIN ### API Cvent ### get_person() ###
# Updated 2022-01-28
# Updated 2022-02-01
@router.get('/person/{e_person_id}', response_model=Resp_Body_Base)
async def get_person(
e_person_id: str = Query(..., min_length=36, max_length=36), # UUID v4; actually the Cvent Contact UUID for a person
@@ -29,7 +29,7 @@ async def get_person(
commons: Common_Route_Params = Depends(common_route_params),
):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
# current_datetime = datetime.datetime.now()
@@ -51,13 +51,17 @@ 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=e_person_id):
# cvent_contact_obj = cvent_contact_obj_result
# else:
# log.info(f'Cvent contact not found with ID: {e_person_id}')
# return mk_resp(data=None, status_code=404, response=commons.response) # Not Found
if cvent_contact_obj_result := get_contact_id(contact_id=e_person_id):
cvent_contact_obj = cvent_contact_obj_result
else:
log.info(f'Cvent contact not found with ID: {e_person_id}')
return mk_resp(data=None, status_code=404, response=commons.response) # Not Found
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_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_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))
@@ -116,18 +120,20 @@ async def get_person(
log.debug(contact_data)
address_data = {}
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')
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)
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
@@ -281,7 +287,20 @@ async def get_person(
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: Need to update Cvent record!!!
# 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 = e_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.
@@ -297,8 +316,8 @@ async def get_person(
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 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
@@ -361,3 +380,4 @@ async def get_person(
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() ###