HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/blueprints/user/__pycache__/models.cpython-310.pyc
o

:�e���@sHddlZddlZddlmZddlmZddlZddlZddl	Z	ddl
Z
ddlZddlm
Z
ddlmZddlmZddlmZddlZddlmZmZdd	lmZdd
lmZddlmZmZddlm Z dd
l!m"Z"ddl#m$Z$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+e�,e-�ZdZ.Gdd�dee$j/�Z0Gdd�deee$j/�Z1dS)�N)�OrderedDict)�md5)�current_app)�	UserMixin)�UUID)�URLSafeTimedSerializer)�or_�and_)�text)�hybrid_property)�
ResourceMixin�
AwareDateTime)�Agent)�Appointment)�db�bcrypt)�
ReportUserTie)�convert_to_deltatime)�
relativedeltai�Qc@s�eZdZdZejejejddd�ddd�Zejejejddd�dd	�Z	ejd
e�
�ddd
�Zedd��Z
edd��Zedd��Zedd��Zedd��ZdS)�UserExternalApiAutoPostTie�user_external_api_access_tiezusers.id�users_id_user_access_tie_fkey)�nameT)�primary_key�indexz!external_api_service_providers.id�(service_provider_id_user_access_tie_fkey�r�
is_allowedF�0��nullable�server_defaultcCstj�tj|k���}|S)z�
        Returns a list of existing user/external service provider ties.

        :return: list of user/external api service provider tie objects
        )r�query�filter�user_id�all)�clsr$�ties�r(�B/home/arjun/projects/buyercall/buyercall/blueprints/user/models.py�get_existing_ties2sz,UserExternalApiAutoPostTie.get_existing_tiescCsnd}ddlm}m}tj�|��|��|j|k��|j	|k|j
���}|r5tj�tj
|ktj|jk���}|S)z�
        Returns an existing user/external service provider tie.

        :return: a user/external api service provider tie object
        N���0ExternalApiServiceProvidersPartnershipAccountTie�ExternalApiServiceProviders)�partnership.modelsr-r.r�sessionr"�joinr#r�partnership_account_id�active�firstrr$� external_api_service_provider_id�id)r&r$r2�service_provider_name�service_provider_tier-r.�service_providerr(r(r)�!get_service_provider_access_state=s(
��

��z<UserExternalApiAutoPostTie.get_service_provider_access_statec
Cs�ddlm}m}tj�|��|��|j|k��|j	|k��
�}|ritj�tj|ktj
|jk��
�}|r?||_tj�tj�|_n#t�}	||	_|j|	_
||	_tj�tj�|	_tj�tj�|	_tj�|	�tj��dSdS)z<
        Sets a user/external service provider tie.
        r+r,N)r/r-r.rr0r"r1r#rr2r4rr$r5r6r�datetime�now�pytz�utc�
updated_on�
created_on�add�commit)
r&r$r2r7�valuer-r.r9r8�new_tier(r(r)�!set_service_provider_access_stateXs8�

���z<UserExternalApiAutoPostTie.set_service_provider_access_statecCslddlm}m}ddlm}tj�|��|��	|j
|k|jdk��t��	tj
|ktjdk��|j���}|S)z�
        Returns a list of service providers the user has access to.

        :return: a external api service provider list
        r+r,r)�FormLogT)r/r-r.�&buyercall.blueprints.form_leads.modelsrFrr0r"r1r#r2r3rr$r�order_byrr%)r&r$r2r-r.rF�service_providersr(r(r)�get_allowed_service_providers{s
��
z8UserExternalApiAutoPostTie.get_allowed_service_providerscCs�ddlm}m}ddlm}g}tj�|j|j	��
|��|j|k|j
dk��
t��tj|ktjdk���}|D]}	|	d|	dg}
|�||	d�}|
�|�|�|
�q7|S)z�
        Returns a list of service providers the user has access to including if form logs exist.

        :return: a external api service provider list
        r+r,r)�ExternalApiFormLeadPostTieT�)r/r-r.rGrKrr0r"r6rr1r#r2r3rr$rr%�existing_posts_for_lead�append)r&r$r2�form_lead_idr-r.rK�resultrI�provider�	new_entry�
logs_existr(r(r)�1get_allowed_service_providers_with_form_log_count�s$
��
zLUserExternalApiAutoPostTie.get_allowed_service_providers_with_form_log_countN)�__name__�
__module__�__qualname__�
__tablename__r�Column�Integer�
ForeignKeyr$r5�Booleanr�classmethodr*r:rErJrTr(r(r(r)r"s.���



"
rcs�eZdZegd��Zegd��ZdZdZej	ej
dd�Zej	edd�de
jdd�Zej	ej
ejd	d
d
d�ddd�Zej	ej
ejd
d
d
d�ddd�Zejedddd�Zejeddd�Zejeddd�Zej	ejeddi�dddd�Zej	de��ddd�Zej	e��dd�Zej	e��dddd�Z ej	e�!d�ddd �Z"ej	e�!d!�dddd"d#�Z#ej	e�!d$�dd"d�Z$ej	d%e��ddd�Z%ej	d&e��ddd�Z&ej	d'e��ddd�Z'ej	d(e��ddd�Z(ej	d)e��ddd�Z)ej	d*e��ddd�Z*ej	ej
dd+d,�Z+e�	e,��Z-e�	e�!d-��Z.e�	e,��Z/e�	e�!d-��Z0ej	e�!d$�ddd"d�Z1ej	e�!d$�ddd"d�Z2ej	ejddd�Z3ej	e�
�dd.d,�Z4ej	e��dddd�Z5e6d/d0��Z7e6d1d2��Z8e8j9d3d2��Z8ej	e�!d4�dd"d�Z:ej	e�!d5�dd"d�Z;e�	ej
�Z<e�	e�!d$��Z=e�	e�!d$��Z>ej	ejddd6d7�Z?ej	ejddd6d7�Z@ej	ejddd6d7�ZAej	ejddd6d7�ZBej	ejddd6d7�ZCej	ej
ejd8d
d
d�ddd�ZDej	e�!d9�dd:d�ZEej	e��dd6d�ZFej	ejddd6d7�ZGej	e�!d;�dd"d�ZHej	e��dd6d�ZIej	e��dd<d�ZJ�fd=d>�ZKeLd?d@��ZMeLdAdB��ZNeLdCdD��ZOeLdEdF��ZPeLdGdH��ZQeLdIdJ��ZReLdKdL��ZSeLdMdN��ZTeLdOdP��ZUeLdQdR��ZVeLdSdT��ZWeLdUdV��ZXeLdWdX��ZYeLd�dZd[��ZZeLd�d\d]��Z[eLd�d^d_��Z\d`da�Z]dbdc�Z^d�ddde�Z_d�dgdh�Z`didj�Zae6dkdl��Zbe6dmdn��Zce6dodp��Zde6dqdr��Zee6dsdt��Zfe6dudv��Zge6dwdx��Zhe6dydz��Zie6d{d|��Zje6d}d~��Zke6dd���Zle6d�d���ZmeLd�d���ZneLd�d���Zoe6d�d���Zpd�d��Zqd�d��ZreLd�d�d���Zs�ZtS)��User))�guest�Guest)�member�Member)�admin�Admin)�agentr)�partner�Partner)�
limitsysadminzLimited System Admin)�sysadminzSystem Admin)	)�none�None)�sales�Sales)zinternet saleszInternet Sales)�bdc�BDC)�service�Service)�
management�
Management)zclient relationshipzClient Relationship)�finance�Finance)�other�Other�users)&�sid�partnership_idr2z	agent.sidzagent.timezonezreports.report_idzappointments.sid�roler3�deactivated_on�is_deactivated�email�full_feature_accessr@�
sign_in_count�current_sign_in_on�current_sign_in_ip�last_sign_in_on�last_sign_in_ip�	firstname�lastname�appointment_enabled�appointment_interval�phonenumber�company�	extension�title�
department�
leads_onboard�agents_onboard�outbound_onboard�inbound_onboard�locale�two_factor_auth�	dark_mode�user_avatar�support_notification�push_notification_subscriptionTr)�as_uuid)�unique�defaultrzpartnerships.id�CASCADE)�onupdate�ondelete)rr zpartnership_accounts.id�userF)�backref�uselist�passive_deleteszall, delete-orphan)�back_populates�cascade�partnership_account)r�r�r�
role_typesra)rr r!�	is_active�1r)r r)r r!r��)r�r��)r�rr r!��
is_tos_agreedr�inbound_routing_access�outbound_routing_access�forms_access�external_api_accessr)r r��-�cCs|jrdSdS)z@
        Whether or not the user account is a BDC user.
        TF)�external_bdc��selfr(r(r)�is_bdc_user$szUser.is_bdc_usercCs6|js|jsdSd�|jsdn|j|jsd�S|j�S)Nz{} {}r�)r�r��formatr�r(r(r)r.s��z	User.namecCs4|js|jsdS|js
dS|js|jddS|jS)Nr�)r�r�)r&r(r(r)r7s$���false)r r�r!zpartnership_account_groups.id��eni��truecs.tt|�jdi|��t�|�dd��|_dS)N�passwordr�r()�superr^�__init__�encrypt_password�getr�)r��kwargs��	__class__r(r)r�usz
User.__init__cCsLtj�ttj|ktj|k����}|dur$d|_t�	�|_
tj�
�dSdS)zb
        Deactivate user. The is_active flag will be set to false.

        :return: bool
        NFT)r^r"r#r	r6r2r4r3r;r<r|rr0rB)r&r6r2r�r(r(r)�
deactivate{s"

zUser.deactivatec
Cs^t�|�}
|
dur-|	dvrd}	t|||||||||	|
||
dd�
}tj�|�tj��dSdS)N�r_rarerfraF)
r�r�r�r�r�r~r�r�r{�usernamer2r��
tos_agreementT)r^r�rr0rArB)r&r�r�r�r�r�r~r�r�r{r�r2r��new_password�new_userr(r(r)�create�s
�
zUser.createc
Cs~tj�ttj|ktj|k����}|dur=||_||_||_	||_
||_|
|_||_
|	|_|dvr3d}||_tj��dSdS)zC
        Update the user's details.

        :return: bool
        Nr�raTF)r^r"r#r	r6r2r4r�r�r�r�r~r�r�r�r{rr0rB)
r&r6r2r�r�r�r�r�r~r�r�r{r�r(r(r)�update�s "
zUser.updatecCsN|std�Sd�|�}tj�|�tj�|�tj�|�tj�|�f}tt|��S)z�
        Search a resource by 1 or more fields.

        :param query: Search query
        :type query: str
        :return: SQLAlchemy filter
        r�z%{0}%)	r
r�r^r~�iliker�r�r�r)r&r"�search_query�search_chainr(r(r)�search�s	




�zUser.searchcCs.tj�tj|ktj|kB��tj�d����S)z�
        Find a user by their e-mail or username.

        :param identity: Email or username
        :type identity: str
        :return: User instance
        F)r^r"r#r~r�r}�is_r4)r&�identityr(r(r)�find_by_identity�s
	��zUser.find_by_identitycCs|rt�|d��d�SdS)z�
        Hash a plaintext string using bcrypt.

        :param plaintext_password: Password in plain text
        :type plaintext_password: str
        :return: str
        ��utf-8N)r�generate_password_hash�decode)r&�plaintext_passwordr(r(r)r��s	zUser.encrypt_passwordcCsDtjd}ztj||dgd�}t�|�d��WSty!YdSw)z�
        Obtain a user from de-serializing a signed token.

        :param token: Signed token.
        :type token: str
        :return: User instance or None
        �
SECRET_KEY�HS256)�
algorithms�
user_emailN)r�config�jwtr�r^r�r��	Exception)r&�token�private_key�decoded_payloadr(r(r)�deserialize_token�s
�zUser.deserialize_tokencCsf|jdko|dk}|jduo|du}|s|r1tj�tjdktj|jktj|jk���}|dkr1dSdS)�=
        Determine whether this user is the last admin account.

        :param user: User being tested
        :type user: User
        :param new_role: New role being set
        :type new_role: str
        :param new_active: New active status being set
        :type new_active: bool
        :return: bool
        rcTNrLF)r{r3r^r"r#rzr2�count)r&r��new_role�
new_active�is_changing_roles�is_changing_active�admin_countr(r(r)�
is_last_admins


��zUser.is_last_admincCs\|jdko|dk}|jduo|du}|s|r,tj�tjdktj|jk���}|dkr,dSdS)r�rfTNrLF)r{r3r^r"r#rzr�)r&r�r�r�r�r��
partner_countr(r(r)�is_last_partners

��zUser.is_last_partnercCs6tj�|��|j�|��jddidd�}tj��|S)z�
        Override the general bulk_delete method because we need to delete them
        one at a time while also deleting them on Stripe.

        :param ids: List of ids to be deleted
        :type ids: list
        :return: int
        r3F�fetch)�synchronize_session)rr0r"r#r6�in_r�rB)r&�ids�delete_countr(r(r)�bulk_delete8s


�
zUser.bulk_deletecCsBd}tj�tj|k���}|rd|_tj��|_t	j
��d}|S)z�
        Deactivates a user. Sets the is_deactivated to TRUE and sets the deactivated_on date.
        :param id: User ID to be deactivated
        :type id: int
        :return: boolean
        FT)r^r"r#r6r4r}r;r<r|rr0rB)r&r6rPr�r(r(r)�deactivate_userJs
zUser.deactivate_userc	Cs�t�|�}|��}ddlm}ddlm}m}|j�	|j
|jk���}|j
dkr5|j�	|j
|jk���}n|j�	|j
|jk���}|�|j
||j|j�|S)z�
        Generate a token to reset the password for a specific user.

        :param identity: User e-mail address or username
        :type identity: str
        :return: User instance
        r)�deliver_password_reset_emailr+)�Partnership�PartnershipAccountrf)r^r��serialize_token�buyercall.blueprints.user.tasksr�r/r�r�r"r#r6r2r4r{rz�delayr�logo)	r&r��u�reset_tokenr�r�r��partner_accountrfr(r(r)�initialize_password_reset]s
	�
zUser.initialize_password_resetcCs�|j�|j|k���}tj�|d�}|��dd}t|�}|tj|j	d�}tj�t
|�d�}tj�t
|�d�}	|��}
|	��}t
|�|t
|
�dd�t
|�dd�d�}|�|j|�}
||
vrcd	Sd
S)aR
        Check if a user is available for a specific date and time

        :param user_id: User's system id
        :param date: The request appointment date
        :param start_time: The request appointment start time
        :type user_id: int
        :type date: string
        :type start_time: string
        :return: True
        �%Y-%m-%drL���minutes�%H:%M:%SN�����date�weekday�
start_time�end_timeTF)
r"r#r6r4r;�strptimer	r�	timedeltar��str�time� user_available_appointment_slots)r&r$rr
r��format_date�date_weekdayr�format_start_time�format_end_time�final_start_time�final_end_time�requested_appointment�available_slotsr(r(r)�user_appointment_availabilityxs$�z"User.user_appointment_availabilityNc$	Cs�|j�t|j|k|j�d�|j�d�����}tj�	t
tj���d�}|j
j}t�|�}tj�|�}|�d�}|rUtj�	|d�}	t
|	tdd��dd�}
tj�	|
d�}n|}	t
|	tdd��dd�}
tj�	|
d�}�zW|�r�g}|	}
|
|kr�|
��d	d
}|
|d�}|�|�|
td	d�7}
|
|ksxg}|j
jr�|j
j��}nd
}|d
ks�|j
jdur�|D])}|j
jD]"}|j|dkr�|jr�|j}|j}|d|d||d�}|�|�q�q�n|D]}d}d}|d|d||d�}|�|�q�tj�ttj|ktj�d�tj|	ktj|k����}g}|D]"}|j D]}t
|j�|j��d	d
|j!|j"d�}|�|��q�qg}|D]�}|d}||dk�r�|dk�r�t#|dd��}|tj$|j%d�}tj�	t
|�d�}tj�	t
|�d�} |�&�}!| �&�}"t
|d�|dt
|!�dd�t
|"�dd�d�}#|#|v�r�t
|#d�t
|�k�r�|#d|k�r�n|�|#�t
|"�}||dk�r�|dk�sK�q9|WSWdSt'�y�t(�)d�*t+�,���YdSw)aC
        Retrieve a list of start and end time appointment slots for a specific date an user

        :param user_id: User's system id
        :param date: The date in question
        :type user_id: int
        :type date: string
        :return: list of appointment slot dictionaries for a specific date and user
        FTrrr+)�monthsNi����rLr)rr	)�daysrr	r)rr	�schedule_start_time�schedule_end_timez00:00:00z23:00:00rrrrrr
z2User available appointment slots error message: {})-r"r#r	r6r}r�r�r4r;rrr�todayre�timezoner=r<�strftimerr	rN�	schedulesr��	all_hours�dayr��available_from�available_torr$�appointment_dater%�appointment_slotr
rrr
r�rr��log�errorr��	traceback�
format_exc)$r&r$rr��
date_today�account_timezone�tz�time_now�account_time_nowr�future_date�format_future_date�dates_with_weekdays�
start_dater	�date_and_day�dates_with_schedules�schedule_count�var_dayrr�available_days�appointments�unavailable_slots�appointmentr'�appointment_time_slotr�
schedule_dater
rrrrr�slotr(r(r)r�s�

��



��
����
��
��

�

�
��K�z%User.user_available_appointment_slotscCsn|r|j�t|j|k|jdk��}n	|j�|j|k�}|r-|r-|�t|j|k|j|k��}|r3|��S|��S)a1
        Get users by partnership id.
        :param: is_active_only - Boolean (Is only active users needed)
        :param: count_only - Boolean (Is only count of users needed)
        :param: from_date - Datetime
        :param: to_date - Datetime
        :return: User objects or objects count
        T)r"r#r	rzr3r@r�r%)r&�pid�is_active_only�
count_only�	from_date�to_daterxr(r(r)�get_by_partnerships
��zUser.get_by_partnershipc
Cs�|rF|dkrtjtjd�}|jdd�}|j||||d�S|dkrDtjtjd�}|jd}|jdd�}|j|dd�}|}	|j||||	d�Sd	S|j||d�S)
z^
        :param date_range_expr: type:string, possible values: this_month, last_month
        �
this_month)r.rL)r#)rBrCrD�
last_month)�monthr#)rBN)�pendulumrr=r>�replacerErH)
r&r@rB�date_range_exprr�	first_day�	pre_month�first_day_this_month�first_day_pre_month�last_day_pre_monthr(r(r)� get_by_partnership_datetime_exprs
�z%User.get_by_partnership_datetime_exprcCs|jS)z�
        Return whether the user account is active, this satisfies
        Flask-Login by overwriting the default value.

        :return: bool
        )r3r�r(r(r)r�2szUser.is_activecCs:tjd}t|�}t|j�t|j���g}|�|��	d�S)as
        Return the user's auth token. Use their password as part of the token
        because if the user changes their password we will want to invalidate
        all of their logins across devices. It is completely fine to use
        md5 here as nothing leaks.

        This satisfies Flask-Login by providing a means to create a token.

        :return: str
        r�r�)
rr�rrr6rr��	hexdigest�dumpsr�)r�r��
serializer�datar(r(r)�get_auth_token;s
zUser.get_auth_tokencCs|r	t�|j|�SdS)a+
        Ensure a user is authenticated, and optionally check their password.

        :param with_password: Optionally check their password
        :type with_password: bool
        :param password: Optionally verify this as their password
        :type password: str
        :return: bool
        T)r�check_password_hashr�)r��
with_passwordr�r(r(r)�
authenticatedMs
zUser.authenticated�cCs<tjd}|jtj��tj|d�d�}tj||dd�}|S)a
        Sign and create a token that can be used for things such as resetting
        a password or other tasks that involve a one off token.

        :param expiration: Seconds until it expires, defaults to 1 hour
        :type expiration: int
        :return: JSON
        r�)�seconds)r��expr�)�	algorithm)rr�r~r;�utcnowr
r��encode)r��
expirationr��payloadr�r(r(r)r�\s
�zUser.serialize_tokencCs<|jd7_|j|_|j|_tj�tj�|_||_|�	�S)a
        Update various fields on the user that's related to meta data on his
        account, such as the sign in count and ip address, etc..

        :param ip_address: IP address
        :type ip_address: str
        :return: SQLAlchemy commit results
        rL)
r�r�r�r�r�r;r<r=r>�save)r��
ip_addressr(r(r)�update_activity_trackingss	zUser.update_activity_trackingcCsd}|jdkr	d}t||�S)N�partnershiprcr�)r{�getattr)r��depr(r(r)�"partnership_or_partnership_account�s

z'User.partnership_or_partnership_accountcCs:ddlm}|j�|j|jk���}|s|j�d�}|jS�Nr+�r�rL)	r/r�r"r#r6rzr4r�ry�r�r�rer(r(r)�partnership_sid�s
zUser.partnership_sidcCs6ddlm}d}|j�|j|jk���}|r|j}|S)Nr+�r�)r/r�r"r#r6r2r4ry)r�r��partnership_account_sidr�r(r(r)rn�szUser.partnership_account_sidcCsL|jr|jjr|jjS|jjr|jjjr|jjjS|jr$|jjr$|jjSdS�N)r��subscriptionrer�r(r(r)rp�s
zUser.subscriptioncC�|jdur|jdkrdSdS)zS
        Whether the user account is used in a partnership account or not.
        NrTF)r2r�r(r(r)�is_partnership_account_user��z User.is_partnership_account_usercCrq)zK
        Whether the user account is used in a partnership or not.
        NrTF)rzr�r(r(r)�is_partnership_user�rszUser.is_partnership_usercCs^ddlm}|jdkr-|jr-|jr-|jdkr-|j�t|j|jk|j|jk����}|r-dSdS)z�
        Whether the user account is used to view/acccess/change partnership account groups.
        Checks: Must be an admin role, must have a partnership account ID and must belong to a group.
        r+��PartnershipAccountGroupTiercrTF)	r/rvr{�partnership_account_group_idr2r"r#r	r�)r�rv�group_tie_existsr(r(r)�is_admin_user_with_groups�s
���zUser.is_admin_user_with_groupsc
Cs�tjtjdtjdd�}ddlm}zG|jdkrX|jrX|jrX|jdkrX|j	�
t|j|jk|j|jk����}|rX|dkrXd�
|j�}|�|�d	krXt|�|��}|dkrXWd
SWdStyr}zt�d�WYd
}~dSd
}~ww)zL
        Whether the user account is viewing a partnership account.
        �REDIS_CONFIG_URL�REDIS_CONFIG_PORT��host�portr+rurcr�partner-user-view:{}rLTFz,Error retrieving viewed partnership account.N)�redis�StrictRedisrr�r/rvr{rwr2r"r#r	r�r�r6�exists�intr�r�r(r))r��redis_dbrvrx�keyrP�er(r(r)�is_viewing_partnership�s8�����
��zUser.is_viewing_partnershipc
Cs�tjtjdtjdd�}d�|j�}d}|�|�dkrDz
t|�|��}W|St	yC}zt
�d�|��d}WYd}~|Sd}~ww|S)	z�
        Whether the user account is currently viewing (acting on behalf) of a partnership account.
        Returns -1 if not viewing, partnership account id if viewing.
        rzr{r|r���rLz6Error retrieving viewed partnership account. Error: {}N)r�r�rr�r�r6r�r�r�r�r(r))r�r�r�rPr�r(r(r)�'get_user_viewing_partnership_account_id�s ����z,User.get_user_viewing_partnership_account_idc
C��tjtjdtjdd�}ddlm}z8d}d�|j�}|�|�dkrCt	|�
|��}|d	krF|j�|j|k��
�}|d
urI|j}W|SW|SW|SW|Styh}zt�d�|��d}WYd
}~|Sd
}~ww)�>
        Returns the viewed partnership account name.
        rzr{r|r+rmr�rrLrN�9Error retrieving viewed partnership account name. Error: )r�r�rr�r/r�r�r6r�r�r�r"r#r4rr�r(r)�r�r�r�rPr�r2�accountr�r(r(r)�)get_user_viewing_partnership_account_name�4���	����z.User.get_user_viewing_partnership_account_namec
Cr�)z4
        Returns the viewed partnership id.
        rzr{r|r+rmr�rrLrNz1Error retrieving viewed partnership id. Error: {})r�r�rr�r/r�r�r6r�r�r�r"r#r4rzr�r(r)r�r(r(r)�get_user_viewing_partnership_id+r�z$User.get_user_viewing_partnership_idc
Cs.tjtjdtjdd�}ddlm}zfd}d�|j�}|�|�dkrkt	|�
|��}|dkrn|j�|j|k��
�}|d	urq|jrK|jjrK|jj}W|S|jjr\|jjjr\|jjj}W|S|jrt|jjrw|jjj}W|SW|SW|SW|SW|SW|Sty�}zt�d
�|��d}WYd	}~|Sd	}~ww)r�rzr{r|rrmr�rrLNr�)r�r�rr��'buyercall.blueprints.partnership.modelsr�r�r6r�r�r�r"r#r4rp�planrer�r(r)r�r(r(r)�6get_user_viewing_partnership_account_subscription_planHsR��

�����
�����z;User.get_user_viewing_partnership_account_subscription_planc
Cs�tjtjdtjdd�}d�|�}z|�||�|�|t�d}W|Sty@}zt	�
d�|��d}WYd}~|Sd}~ww)	z�
        Sets the partnership account id of the account the user is viewing.
        Set -1 if not viewing, partnership account id if viewing.
        rzr{r|rTz3Error setting viewed partnership account. Error: {}FN)r�r�rr�r��set�expire�DAYSr�r(r))r&r$r2r�r�rPr�r(r(r)�$set_user_viewing_partnership_accountos�
���z)User.set_user_viewing_partnership_accountc	
Cs ddlm}d}tj�tj|k���}|r�|jdkr�|jr�|j	r�|j	dkr�zM|j�t
|j	|j	k|j|jk����}|j�t
|j	|k|j|jk����}|rd|jdkrg|rj|jdkrm|j|jkrpd}W|SW|SW|SW|SW|SW|Sty�}zt�
d�|��WYd}~|Sd}~ww|S)	ze
        Whether the user account is in the same group as the passed partnership account id.
        r+ruFrcrTzJError checking if user is in the same partnership account group. Error: {}N)r/rvr^r"r#r6r4r{rwr2r	r�r(r)r�)	r&r$r2rvrPr��group_tie_user�group_tie_otherr�r(r(r)�is_in_same_group�s^����
�������������zUser.is_in_same_groupcCst|jdur8ddlm}|j�|j|jk���}|r|jS|jdur8ddlm	}|j�|j|jk���}|r8|jSdS)zJ
        Retrieve the user business type from partnership account
        Nr+rmrjr�)
r2r/r�r"r#r6r4�
business_typerzr�)r�r�r�r�rer(r(r)r��s&
�
�zUser.business_typecC�8ddlm}|j�|j|jk���}|s|j�d�}|Sri)r/r�r"r#r6rzr4r�rkr(r(r)�get_partnership��
zUser.get_partnershipcCr�)Nr+rmrL)r/r�r"r#r6r2r4r�)r�r�r�r(r(r)�get_partnership_account�r�zUser.get_partnership_accountcCs:|durgSdd�tj�|j��|j�|����D�}|S)NcSsg|]}t|d��qS)r)r)�.0�uidr(r(r)�
<listcomp>�sz*User.get_sid_by_emails.<locals>.<listcomp>)rr0r"ryr#r~r�r%)r&�
recipients�
users_sidsr(r(r)�get_sid_by_emails�s*zUser.get_sid_by_emailsro)TFNN)FN)Tr�)rZ)urUrVrWr�ROLE�
DEPARTMENTrX�serialize_onlyrrYrZr6r�uuid�uuid4ryr[rzr2�relationshiprrer�reportsrr:�Enumr{r\r3�DateTimer|r}�Stringr�r~r�r�rr�r�r�r�r�r
r�r�r�r�r�r�r�r�r�rr�r�
expressionr�r�r�r�r�r�r�r�r��two_factor_auth_onboardrwr�r�r�r�r�r�r�r]r�r�r�r�r�r�r�r�r�r�r�rrrrErQr�rVrYr�rdrhrlrnrprrrtryr�r�r�r�r�r�r�r�r�r�r��
__classcell__r(r(r�r)r^�sj
�������������
	


�
�
�
�
���
��












 l	




	

	
	

 



&

"
r^)2r;r*�collectionsr�hashlibr�loggingr(r�rIr�r=�flaskr�flask_loginr�sqlalchemy.dialects.postgresqlr�itsdangerousrr��
sqlalchemyrr	�sqlalchemy.sqlr
�sqlalchemy.ext.hybridr�buyercall.lib.util_sqlalchemyrr
�"buyercall.blueprints.agents.modelsr�(buyercall.blueprints.appointments.modelsr�buyercall.extensionsrr�#buyercall.blueprints.reports.modelsr�buyercall.lib.util_datetimer�dateutil.relativedeltar�	getLoggerrUr��Modelrr^r(r(r(r)�<module>s: