from __future__ import annotations import datetime 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.methods.contact_methods import create_contact_obj, create_update_contact_obj, load_contact_obj, update_contact_obj from app.models.common_field_schema import default_num_bytes from app.models.organization_models import Organization_Base # ### BEGIN ### API Organization Methods ### load_organization_obj() ### # NOTE: This needs to be updated to the newer method template. Like address, contact, or person -STI 2021-06-10 def load_organization_obj( organization_id:int|str, limit: int = 1000, by_alias: bool = True, exclude_unset: bool = True, model_as_dict: bool = False, enabled: str = 'enabled', # enabled, disabled, all inc_contact:bool=False, inc_address:bool=False ) -> Organization_Base|bool: log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if organization_id := redis_lookup_id_random(record_id_random=organization_id, table_name='organization'): pass else: return False if organization_rec := sql_select(table_name='v_organization', record_id=organization_id): pass else: return False #log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(organization_rec) try: organization_obj = Organization_Base(**organization_rec) log.debug(organization_obj) except ValidationError as e: log.error(e.json()) # Updated 2021-06-18 if inc_contact: contact_id = organization_rec.get('contact_id', None) log.debug(contact_id) if contact_result := load_contact_obj( contact_id = contact_id, limit = limit, by_alias = by_alias, exclude_unset = exclude_unset, model_as_dict = model_as_dict, enabled = enabled, inc_address = inc_address, ): organization_obj.contact = contact_result else: organization_obj.contact = None if model_as_dict: return organization_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member else: return organization_obj # ### END ### API Organization Methods ### load_organization_obj() ### # ### BEGIN ### API Organization Methods ### get_organization_rec_list() ### def get_organization_rec_list( for_obj_type: str, for_obj_id: str, limit: int = 1000, enabled: str = 'enabled', # enabled, disabled, all ) -> list|bool: log.setLevel(logging.WARNING) # 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 else: return False data = {} data[f'{for_obj_type}_id'] = for_obj_id # data['for_obj_type'] = for_obj_type sql_obj_type_id = f'`tbl`.{for_obj_type}_id = :{for_obj_type}_id' # if enabled in ['enabled', 'disabled', 'all']: # if enabled == 'enabled': # data['enable'] = True # sql_enabled = f'AND `tbl`.enable = :enable' # elif enabled == 'disabled': # data['enable'] = False # sql_enabled = f'AND `tbl`.enable = :enable' # elif enabled == 'all': # sql_enabled = '' sql_enabled = '' if limit: data['limit'] = limit sql_limit = f'LIMIT :limit' else: sql_limit = '' sql = f""" SELECT `tbl`.id AS 'organization_id', `tbl`.id_random AS 'organization_id_random' FROM `organization` AS `tbl` WHERE {sql_obj_type_id} {sql_enabled} ORDER BY `tbl`.created_on DESC, `tbl`.updated_on DESC {sql_limit}; """ if organization_rec_li_result := sql_select(data=data, sql=sql, as_list=True): organization_rec_li = organization_rec_li_result else: organization_rec_li = [] log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(organization_rec_li_result) return organization_rec_li # ### END ### API Organization Methods ### get_organization_rec_list() ### # ### BEGIN ### API Organization Methods ### update_organization_obj() ### # NOTE: This will create an organization and then also create a linked contact if organization_obj.contact data is passed. The create_contact_obj will create a contact and then also create a linked address if organization_obj.contact.address data is passed. # Reviewed and updated 2021-08-10 def update_organization_obj( organization_id: int|str, # Ideally the int ID should be passed. This allows for updating of the id_random value. organization_obj_up: Organization_Base, create_sub_obj: bool = False, ) -> bool: log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if organization_obj_up.contact_id and organization_obj_up.contact: contact_id = organization_obj_up.contact_id contact_obj_up = organization_obj_up.contact log.debug(contact_id) log.debug(contact_obj_up) if contact_obj_up_result := update_contact_obj( contact_id = contact_id, contact_dict_obj = contact_obj_up, create_sub_obj = create_sub_obj, ): log.debug(contact_obj_up_result) else: log.debug(contact_obj_up_result) return False elif organization_obj_up.contact and not organization_obj_up.contact.id: # NOTE: This will blindly create a new contact even if there was one associated but the organization.contact_id was not found. contact_obj_in = organization_obj_up.contact log.debug(contact_obj_in) if contact_obj_in_result := create_contact_obj( account_id = contact_obj_in.account_id, contact_dict_obj=contact_obj_in, ): # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(contact_obj_in_result) organization_obj_up.contact_id = contact_obj_in_result else: # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(contact_obj_in_result) return False organization_dict_up = organization_obj_up.dict(by_alias=False, exclude_unset=True, exclude={'contact', 'person', 'user'}) log.debug(organization_dict_up) if organization_obj_up_result := sql_update(data=organization_dict_up, table_name='organization', rm_id_random=True): log.debug(organization_obj_up_result) return True else: log.debug(organization_obj_up_result) return False # ### END ### API Organization Methods ### update_organization_obj() ### # ### BEGIN ### API Organization Methods ### create_update_organization_obj() ### def create_update_organization_obj( organization_id: int|str|None, # Ideally the int ID should be passed. This allows for updating of the id_random value. organization_obj: Organization_Base, process_contact: bool = False, ) -> bool: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if organization_id: if organization_id := redis_lookup_id_random(record_id_random=organization_id, table_name='organization'): pass else: return False organization_obj.id = organization_id else: # Insert record now and update later organization_dict_in = organization_obj.dict(by_alias=False, exclude_unset=True, exclude={'contact', 'person', 'user'}) log.debug(organization_dict_in) organization_in_result = sql_insert( data = organization_dict_in, table_name = 'organization', rm_id_random = True, id_random_length = default_num_bytes, ) log.debug(organization_in_result) if isinstance(organization_in_result, bool) and organization_in_result is True: return organization_in_result elif isinstance(organization_in_result, int): organization_id = organization_in_result organization_obj.id = organization_id else: return False # This should not happen. # Process contact data if process_contact and organization_obj.contact: contact_obj = organization_obj.contact contact_obj.for_type = 'organization' contact_obj.for_id = organization_id contact_id = organization_obj.contact_id_random contact_result = create_update_contact_obj( contact_id = contact_id, contact_obj = contact_obj, process_address = True, # Setting to True under the assumption that if there is contact information then there is probably an address. ) log.debug(contact_result) if isinstance(contact_result, bool) and contact_result is True: pass # Do not need to update organization object. elif isinstance(contact_result, bool) and contact_result is False: pass # Do not need to update organization object. elif isinstance(contact_result, int): organization_obj.contact_id = contact_result # pass # Do not need to update organization object. else: log.warning('Something may have gone wrong while trying to create or update a contact.') # Process organization data organization_dict_up = organization_obj.dict(by_alias=False, exclude_unset=True, exclude={'contact', 'person', 'user'}) log.debug(organization_dict_up) # Update record organization_up_result = sql_update( data = organization_dict_up, table_name = 'organization', rm_id_random = True, ) log.debug(organization_up_result) if isinstance(organization_up_result, bool) and organization_up_result is True: return organization_id elif isinstance(organization_up_result, bool) and organization_up_result is False: return False elif isinstance(organization_up_result, int): return organization_up_result else: return False # ### END ### API Organization Methods ### create_update_organization_obj() ###