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_forms/buyercall/buyercall/blueprints/api2/doc/endpoints/contacts.py
import logging
import json
import traceback

from flask import (
    Blueprint,
    make_response,
    request,
    jsonify,
    current_app as app)
from buyercall.lib.util_crypto import AESCipher
from flask import Blueprint, jsonify, make_response
from buyercall.lib.util_rest import rest_partnership_account, \
    rest_partnership, requires_auth, \
    rest_is_partnership_account, rest_is_partnership, rest_api_token_id
from flask_restx import Resource
from sqlalchemy import and_

from buyercall.lib.util_rest import rest_partnership, requires_auth, rest_is_partnership, rest_api_token_id
from buyercall.blueprints.api2.doc import serializers
from buyercall.blueprints.filters import format_phone_number
from buyercall.blueprints.api2.restplus import api
from buyercall.blueprints.partnership.models import PartnershipAccount
from buyercall.blueprints.contacts.models import Contact
from buyercall.blueprints.agents.models import Agent
from sqlalchemy import func, or_, and_, extract, text

log = logging.getLogger(__name__)

# DISABLE ENDPOINT
# ns = api.namespace('Contacts', description='Operations related to contacts.', path='/accounts')


# @ns.route('/<int:paid>/contact')
@api.doc(responses={200: 'OK',
                    400: 'Error performing operation.',
                    401: 'Unauthorized request.'},
         params={'paid': 'The partner account Id'})
class ApiContactSinglePost(Resource):

    @api.response(204, 'Contact successfully created.')
    @api.expect(serializers.contact_add, validate=True)
    @requires_auth
    def post(self, paid):
        """
        Create a single contact for a partnership account.

        <p>
        The Contact API POST endpoint should be used to create or import a new contact for a partner account.
        Contacts are seen as unique based on phone number.
        If you were to add a new contact with the same phone number as an existing contact
        no new contact will be added and the existing contact will be updated with new contact information.
        <br />
        This POST endpoint should be used to import a single contact. If you would like to import multiple contacts
        please use the Contacts API POST endpoint below.
        </p>
        <br />
        <p>
        You will require a partner authentication token and a partner account to make a successful request.
        A response will be returned, similar to the example below, based on a successful request:
        <br />
        <br />
        </p>
         <pre class="code-background" style="color: white">
        {
          "agent_id": 2,
          "contact_id": 109,
          "credit_information": {
            "approved": false,
            "score": 750,
            "trades": [
              {
                "accountNumber": "62063570877071001",
                "balanceAmount": 20332,
                "financeType": "Loan",
                "monthlyPaymentAmount": 449,
                "numberMonthsRemaining": 0,
                "subcode": "1638640",
                "subscriberDisplayName": "CAPITAL ONE AUTO FINAN"
              }
            ]},
          "firstname": "John",
          "lastname": "Doe",
          "partnership_account_id": 1,
          "phonenumber": "+17732908841"
        }
        </pre>

        """

        if rest_is_partnership and rest_partnership is not None:
            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                received = request.get_json()
                result_agent_id = None
                result_birthday = None
                result_avatar = None
                result_large_avatar = None
                result_email = None
                result_address_1 = None
                result_address_2 = None
                result_city = None
                result_state = None
                result_zip = None
                result_country = None
                result_ip = None
                result_is_deactivated = None
                result_is_do_not_call = None
                result_is_unsubscribe = None
                result_status = None
                result_caller_id = None
                result_phonenumber = None
                result_api_token_id = int(rest_api_token_id)
                response = None
                result_contact_id = None

                if received:
                    result_phonenumber = format_phone_number(received['phonenumber'])

                    contact_exists = Contact\
                        .query\
                        .filter(and_(Contact.phonenumber_1 == result_phonenumber,
                                     Contact.partnership_account_id == paid))\
                        .first()

                    if 'agent_id' in received:
                        result_agent_id = received['agent_id']

                        if result_agent_id is not None and result_agent_id > 0:
                            agent_found = Agent\
                                .query\
                                .filter(and_(Agent.id == result_agent_id, Agent.partnership_account_id == paid))\
                                .first()

                            if not agent_found:
                                return api.abort(code=400, message="Error creating contact. Agent ID not found.")

                    if 'birthday' in received:
                        result_birthday = received['birthday']

                    if 'avatar' in received:
                        result_avatar = received['avatar']

                    if 'large_avatar' in received:
                        result_large_avatar = received['large_avatar']

                    if 'email' in received:
                        result_email = received['email']

                    if 'address_1' in received:
                        result_address_1 = received['address_1']

                    if 'address_2' in received:
                        result_address_2 = received['address_2']

                    if 'city' in received:
                        result_city = received['city']

                    if 'state' in received:
                        result_state = received['state']

                    if 'country' in received:
                        result_country = received['country']

                    if 'zip' in received:
                        result_zip = received['zip']

                    if 'ip' in received:
                        result_ip = received['ip']

                    if 'is_deactivated' in received:
                        result_is_deactivated = received['is_deactivated']

                    if 'status' in received:
                        result_status = received['status']

                    if 'is_do_not_call' in received:
                        result_is_do_not_call = received['is_do_not_call']

                    if 'is_unsubscribe' in received:
                        result_is_unsubscribe = received['is_unsubscribe']

                    if 'caller_id' in received:
                        result_caller_id = received['caller_id']

                    if contact_exists:
                        result_contact_id = contact_exists.id
                        contact_updated = Contact.api_update(paid, result_api_token_id, result_contact_id, received['firstname'],
                                                             received['lastname'], result_phonenumber,
                                                             result_agent_id, result_birthday, result_avatar,
                                                             result_large_avatar, result_email, result_address_1,
                                                             result_address_2, result_city, result_state,
                                                             result_country, result_zip, result_ip,
                                                             result_is_deactivated, result_status,
                                                             result_is_do_not_call, result_is_unsubscribe,
                                                             result_caller_id)

                        if not contact_updated:
                            return api.abort(code=400, message="Error creating contact.")
                        else:
                            if result_agent_id is None:
                                result_agent_id = contact_exists.agent_id

                            response = {
                                'agent_id': result_agent_id,
                                'contact_id': result_contact_id,
                                'firstname': received['firstname'],
                                'lastname': received['lastname'],
                                'phonenumber': result_phonenumber,
                                'partnership_account_id': partnership_account.id
                            }
                    else:
                        params = {
                            'firstname': received['firstname'],
                            'lastname': received['lastname'],
                            'phonenumber_1': result_phonenumber,
                            'agent_id': result_agent_id,
                            'birthday': result_birthday,
                            'avatar': result_avatar,
                            'large_avatar': result_large_avatar,
                            'email': result_email,
                            'address_1': result_address_1,
                            'address_2': result_address_2,
                            'city': result_city,
                            'state': result_state,
                            'country': result_country,
                            'zip': result_zip,
                            'ip': result_ip,
                            'is_deactivated': result_is_deactivated,
                            'status': result_status,
                            'is_do_not_call': result_is_do_not_call,
                            'is_unsubscribe': result_is_unsubscribe,
                            'caller_id': result_caller_id,
                            'partnership_account_id': paid,
                            'api_token_id': result_api_token_id,
                            'external_source_type': 'api'
                        }
                        result_contact_id = Contact.api_create(params)

                        if result_contact_id is None or result_contact_id <= 0:
                            return api.abort(code=400, message="Error creating contact.")
                        else:
                            from buyercall.blueprints.mobile.utils import send_agent_push_notification
                            send_agent_push_notification(result_contact_id)
                            response = {
                                'agent_id': result_agent_id,
                                'contact_id': result_contact_id,
                                'firstname': received['firstname'],
                                'lastname': received['lastname'],
                                'phonenumber': result_phonenumber,
                                'partnership_account_id': partnership_account.id
                            }

                    if response:
                        contact = Contact\
                            .query\
                            .filter(Contact.id == result_contact_id,
                                    Contact.partnership_account_id == paid)\
                            .first()

                        from buyercall.blueprints.api2.doc.endpoints.credit_checks import CreditVerification
                        valid_contact, valid_birth_day, error_message = CreditVerification.all_credit_check_fields_exits(contact)

                        if not valid_contact:
                            response['credit_information'] = {
                                'warning': 'Insufficient contact data provided.'
                            }
                        else:
                            try:
                                credit_report_valid, credit_report, error_message = CreditVerification.get_credit_check_report(contact, valid_birth_day)

                                if not credit_report_valid or not credit_report:
                                    response['credit_information'] = {
                                        'warning': 'Insufficient contact data provided.'
                                    }
                                else:
                                    crypto_key = app.config['CRYPTO_SECRET_KEY']
                                    cipher = AESCipher(crypto_key)

                                    decrypted_score = cipher.decrypt(credit_report.credit_score)
                                    converter_score = 0
                                    if decrypted_score:
                                        converter_score = int(decrypted_score)

                                    decrypted_trades = cipher.decrypt(credit_report.trades)
                                    converted_trades = json.loads(decrypted_trades)
                                    if 'trades' in converted_trades:
                                        converted_trades = converted_trades['trades']
                                    else:
                                        converted_trades = {}

                                    response['credit_information'] = {
                                        'approved': credit_report.is_approved,
                                        'score': converter_score,
                                        'trades': converted_trades
                                    }
                            except:
                                log.error("Cannot check credit on contact {}, partnership account {} and got error : {}".format(contact.id, paid, traceback.format_exc()))
                                response['credit_information'] = {
                                    'warning': 'Unable to retrive data.'
                                }

                        return jsonify(
                            response
                        )
                    else:
                        return api.abort(code=400, message="Error creating contact.")
                else:
                    return api.abort(code=400, message="Error creating contact.")
            else:
                return api.abort(404, message='Partnership account not found.')
        else:
            return api.abort(401)


# @ns.route('/<int:paid>/contacts/<int:aid>')
@api.doc(responses={200: 'OK',
                    400: 'Error performing operation.',
                    401: 'Unauthorized request.'},
         params={'paid': 'The partner account Id',
                 'aid': 'The agent Id'})
class ApiContactGet(Resource):
    @requires_auth
    def get(self, paid, aid):
        """
        Retrieves contacts of a partnership account associated with a specific agent.

        <p>
        The Contacts GET endpoint should be used to return contacts for a specific agent and partner account.
        </p>
        <br />
        <p>
        You require a partner authentication token, a partner account id and agent id to make a successful request.
         A response will be returned, similar to the example below, based
        on a successful request:
        <br />
        <br />
        </p>
         <pre class="code-background" style="color: white">
        {
          "contacts": [
            {
              "address_1": "10 Main St",
              "address_2": "Apt 2",
              "agent_id": 2,
              "avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
              "birthday": "13 Feb 1984",
              "caller_id": "M Pearson",
              "city": "Chicago",
              "country": "USA",
              "created_on": "2019-09-09 21:11:10",
              "deactivated_on": "",
              "email": "harry@buyercall.com",
              "firstname": "Sue",
              "id": 19,
              "ip": "127.0.4.1",
              "is_deactivated": false,
              "is_do_not_call": false,
              "is_unsubscribe": false,
              "large_avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
              "lastname": "Pearson",
              "phonenumber": "+17732909657",
              "state": "IL",
              "status": "new lead",
              "updated_on": "2019-09-09 21:13:03",
              "zip": "60613"
            },
            {
              "address_1": "10 Apple Street",
              "address_2": "Mount Pleasant",
              "agent_id": 2,
              "avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
              "birthday": "21 June 1984",
              "caller_id": "",
              "city": "New York",
              "country": "USA",
              "created_on": "2019-09-09 21:01:54",
              "deactivated_on": "",
              "email": "user@company.com",
              "firstname": "Perry",
              "id": 18,
              "ip": "127.0.0.1",
              "is_deactivated": false,
              "is_do_not_call": false,
              "is_unsubscribe": false,
              "large_avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
              "lastname": "Smith",
              "phonenumber": "+16643309090",
              "state": "New York",
              "status": "general interest",
              "updated_on": "2019-09-09 21:13:49",
              "zip": "10001"
            }
          ]
        }
        </pre>

        """
        if rest_is_partnership and rest_partnership is not None:
            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                contact_list = []

                contacts = Contact.query \
                    .filter(and_(Contact.partnership_account_id == paid, Contact.agent_id == aid)) \
                    .all()

                if contacts is not None:
                    for contact in contacts:

                        result_agent_id = -1

                        if contact.agent_id is not None:
                            result_agent_id = contact.agent_id

                        add_contact = {
                            'id': contact.id,
                            'created_on': contact.created_datetime,
                            'updated_on': contact.updated_datetime,
                            'firstname': contact.firstname,
                            'lastname': contact.lastname,
                            'phonenumber': contact.phonenumber_1,
                            'agent_id': result_agent_id,
                            'birthday': contact.birthday,
                            'avatar': contact.avatar,
                            'large_avatar': contact.large_avatar,
                            'email':  contact.email,
                            'address_1': contact.address_1,
                            'address_2': contact.address_2,
                            'city': contact.city,
                            'state': contact.state,
                            'country': contact.country,
                            'zip': contact.zip,
                            'ip': contact.ip,
                            'status': contact.status,
                            'is_do_not_call': contact.is_do_not_call,
                            'is_unsubscribe': contact.is_unsubscribe,
                            'caller_id': contact.caller_id,
                            'is_deactivated': contact.is_deactivated,
                            'deactivated_on': contact.deactivated_on_datetime
                        }

                        contact_list.append(add_contact)

                return jsonify(
                    contacts=contact_list)
            else:
                return api.abort(404, message='Partnership account not found.')
        else:
            return api.abort(401)


# @ns.route('/<int:paid>/contacts')
@api.doc(responses={200: 'OK',
                    400: 'Error performing operation.',
                    401: 'Unauthorized request.'},
         params={'paid': 'The partner account Id'})
class ApiContactMultiPost(Resource):
    @api.response(204, 'Contact(s) successfully created.')
    @api.expect(serializers.contacts_add, validate=True)
    @requires_auth
    def post(self, paid):
        """
        Create multiple contacts for a partnership account.

        <p>
       The Contacts API POST endpoint should be used to create or import multiple contacts for a partner account.
       Contacts are seen as unique based on phone number.
       If you were to add contacts with the same phone number no new contacts will be
        added and the existing contact will be updated with new contact information.
        <br />
        This POST endpoint should be used to import multiple contacts. If you would like to import a single contact
        please use the Contact API POST endpoint above.
        </p>
        <br />
        <p>
        You will require a partner authentication token and a partner account to make a successful request.
        A response will be returned, similar to the example below, based
        </p>
        <br /><br />
         <pre class="code-background" style="color: white">
        {
          "contacts": [
            {
              "agent_id": 2,
              "contact_id": 19,
              "firstname": "Sue",
              "lastname": "Pearson",
              "phonenumber": "+17732909657"
            },
            {
              "agent_id": 3,
              "contact_id": 20,
              "firstname": "Michelle",
              "lastname": "Connor",
              "phonenumber": "+16643305644"
            }
          ],
          "partnership_account_id": 1
        }
        </pre>

        """
        if rest_is_partnership and rest_partnership is not None:
            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                received = request.get_json()
                contacts_list = []

                if received is not None:

                    if 'contacts' in received:
                        contacts = received['contacts']
                        result_api_token_id = int(rest_api_token_id)

                        for contact in contacts:
                            error_message = 'Error adding contact.'
                            result_agent_id = None
                            result_birthday = None
                            result_avatar = None
                            result_large_avatar = None
                            result_email = None
                            result_address_1 = None
                            result_address_2 = None
                            result_city = None
                            result_state = None
                            result_zip = None
                            result_country = None
                            result_ip = None
                            result_is_deactivated = None
                            result_is_do_not_call = None
                            result_is_unsubscribe = None
                            result_status = None
                            result_caller_id = None
                            result_phonenumber = None
                            entity_exists = False

                            if contact:
                                result_phonenumber = format_phone_number(contact['phonenumber'])
                                phonenumber_exists = Contact \
                                    .query \
                                    .filter(and_(Contact.phonenumber_1 == result_phonenumber,
                                                 Contact.partnership_account_id == paid)) \
                                    .first()

                                if phonenumber_exists:
                                    entity_exists = True

                                if 'agent_id' in contact:
                                    result_agent_id = contact['agent_id']

                                    if result_agent_id is not None and result_agent_id > 0:
                                        agent_found = Agent.query.filter(
                                            and_(Agent.id == result_agent_id, Agent.partnership_account_id == paid)
                                        ).first()

                                        if not agent_found:
                                            error_agent_found = True
                                            error_message = "Error creating contact. Agent ID not found."

                                if 'birthday' in contact:
                                    result_birthday = contact['birthday']

                                if 'avatar' in contact:
                                    result_avatar = contact['avatar']

                                if 'large_avatar' in contact:
                                    result_large_avatar = contact['large_avatar']

                                if 'email' in contact:
                                    result_email = contact['email']

                                if 'address_1' in contact:
                                    result_address_1 = contact['address_1']

                                if 'address_2' in contact:
                                    result_address_2 = contact['address_2']

                                if 'city' in contact:
                                    result_city = contact['city']

                                if 'state' in contact:
                                    result_state = contact['state']

                                if 'country' in contact:
                                    result_country = contact['country']

                                if 'zip' in contact:
                                    result_zip = contact['zip']

                                if 'ip' in contact:
                                    result_ip = contact['ip']

                                if 'is_deactivated' in contact:
                                    result_ip = contact['is_deactivated']

                                if 'status' in contact:
                                    result_status = contact['status']

                                if 'is_do_not_call' in contact:
                                    result_is_do_not_call = contact['is_do_not_call']

                                if 'is_unsubscribe' in contact:
                                    result_is_unsubscribe = contact['is_unsubscribe']

                                if 'caller_id' in contact:
                                    result_caller_id = contact['caller_id']

                                if entity_exists:
                                    contact_updated = Contact.api_update(
                                        paid, result_api_token_id, phonenumber_exists.id,
                                        contact['firstname'],
                                        contact['lastname'], result_phonenumber,
                                        result_agent_id, result_birthday,
                                        result_avatar,
                                        result_large_avatar, result_email,
                                        result_address_1,
                                        result_address_2, result_city, result_state,
                                        result_country, result_zip, result_ip,
                                        result_is_deactivated,
                                        result_status,
                                        result_is_do_not_call, result_is_unsubscribe,
                                        result_caller_id
                                    )

                                    if contact_updated:
                                        contacts_list.append({
                                            'agent_id': result_agent_id,
                                            'contact_id': phonenumber_exists.id,
                                            'firstname': contact['firstname'],
                                            'lastname': contact['lastname'],
                                            'phonenumber': result_phonenumber})
                                    else:
                                        contacts_list.append({
                                            'agent_id': result_agent_id,
                                            'message': error_message,
                                            'firstname': contact['firstname'],
                                            'lastname': contact['lastname'],
                                            'phonenumber': result_phonenumber})
                                else:
                                    params = {
                                        'firstname': contact['firstname'],
                                        'lastname': contact['lastname'],
                                        'phonenumber_1': result_phonenumber,
                                        'agent_id': result_agent_id,
                                        'birthday': result_birthday,
                                        'avatar': result_avatar,
                                        'large_avatar': result_large_avatar,
                                        'email': result_email,
                                        'address_1': result_address_1,
                                        'address_2': result_address_2,
                                        'city': result_city,
                                        'state': result_state,
                                        'country': result_country,
                                        'zip': result_zip,
                                        'ip': result_ip,
                                        'is_deactivated': result_is_deactivated,
                                        'status': result_status,
                                        'is_do_not_call': result_is_do_not_call,
                                        'is_unsubscribe': result_is_unsubscribe,
                                        'caller_id': result_caller_id,
                                        'partnership_account_id': paid,
                                        'api_token_id': result_api_token_id,
                                        'external_source_type': 'api'
                                    }
                                    contact_id = Contact.api_create(params)

                                    if contact_id > 0:
                                        from buyercall.blueprints.mobile.utils import send_agent_push_notification
                                        send_agent_push_notification(contact_id)
                                        contacts_list.append({
                                            'agent_id': result_agent_id,
                                            'contact_id': contact_id,
                                            'firstname': contact['firstname'],
                                            'lastname': contact['lastname'],
                                            'phonenumber': result_phonenumber})
                                    else:
                                        contacts_list.append({
                                            'agent_id': result_agent_id,
                                            'message': error_message,
                                            'firstname': contact['firstname'],
                                            'lastname': contact['lastname'],
                                            'phonenumber': result_phonenumber})

                        return jsonify(contacts=contacts_list,
                                       partnership_account_id=paid)
                    else:
                        log.error('Partnership account: {} has a name of "{}".'.
                                  format(partnership_account.id, partnership_account.name))
                        return api.abort(code=400,
                                         message="Error creating contact. Company name unknown."
                                                 " Please ensure the partnership account name is set."
                                         )
                else:
                    return api.abort(code=400, message="Error creating contact.")
            else:
                return api.abort(404, message='Partnership account not found.')
        else:
            return api.abort(401)

    @requires_auth
    @api.response(204, 'Contact successfully deleted.')
    def delete(self, paid, cid):
        """
        Deletes contact details.

        <p>
        The Contacts API DELETE endpoint should be used to delete a specific contact for a partner account.
        </p>
        <br />
        <p>
        You will require a partner authentication token, a partner account id as well as a contact Id to make a
        successful request.
        </p>

        """
        final_result = False

        if rest_is_partnership and rest_partnership is not None:
            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                final_result = Contact.api_deactivate(cid, partnership_account.id)

            if final_result:
                return final_result, 204
            else:
                api.abort(code=400, message="Error deleting contact.")
        else:
            return api.abort(401)

    @api.response(204, 'Contact successfully updated.')
    @api.expect(serializers.contact_edit, validate=True)
    @requires_auth
    def put(self, paid, cid):
        """
        Update a contact for a partnership account.
        <P>
        This Contacts API PUT endpoint can be used to update contacts for an account associated with a partnership.
        </P>
         <br />
        <p>
        You will require a partner authentication token, a partner account id as well as a contact Id to make a
        successful request.
        </p>

        """
        if rest_is_partnership and rest_partnership is not None:

            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                received = request.get_json()

                result_firstname = None
                result_lastname = None
                result_phonenumber = None
                result_agent_id = None
                result_birthday = None
                result_avatar = None
                result_large_avatar = None
                result_email = None
                result_address_1 = None
                result_address_2 = None
                result_city = None
                result_state = None
                result_zip = None
                result_country = None
                result_ip = None
                result_is_deactivated = None
                result_is_do_not_call = None
                result_is_unsubscribe = None
                result_status = None
                result_caller_id = None
                result_api_token_id = int(rest_api_token_id)

                if received is not None:

                    if 'firstname' in received:
                        result_firstname = received['firstname']

                    if 'lastname' in received:
                        result_lastname = received['lastname']

                    if 'phonenumber' in received:
                        result_phonenumber = format_phone_number(received['phonenumber'])

                        phonenumber_exists = Contact\
                            .query\
                            .filter(and_(Contact.phonenumber_1 == result_phonenumber,
                                         Contact.partnership_account_id == paid))\
                            .first()

                        if phonenumber_exists and phonenumber_exists.id != cid:
                            return api.abort(code=400, message="Error updating contact. "
                                                               "Phonenumber already in use.")

                    if 'agent_id' in received:
                        result_agent_id = received['agent_id']
                        agent_found = Agent\
                            .query\
                            .filter(and_(Agent.id == result_agent_id, Agent.partnership_account_id == paid))\
                            .first()

                        if not agent_found:
                            return api.abort(code=400, message="Error updating contact. Agent ID not found.")

                    if 'birthday' in received:
                        result_birthday = received['birthday']

                    if 'avatar' in received:
                        result_avatar = received['avatar']

                    if 'large_avatar' in received:
                        result_large_avatar = received['large_avatar']

                    if 'email' in received:
                        result_email = received['email']

                    if 'address_1' in received:
                        result_address_1 = received['address_1']

                    if 'address_2' in received:
                        result_address_2 = received['address_2']

                    if 'city' in received:
                        result_city = received['city']

                    if 'state' in received:
                        result_state = received['state']

                    if 'country' in received:
                        result_country = received['country']

                    if 'zip' in received:
                        result_zip = received['zip']

                    if 'ip' in received:
                        result_ip = received['ip']

                    if 'is_deactivated' in received:
                        result_is_deactivated = received['is_deactivated']

                    if 'status' in received:
                        result_status = received['status']

                    if 'is_do_not_call' in received:
                        result_is_do_not_call = received['is_do_not_call']

                    if 'is_unsubscribe' in received:
                        result_is_unsubscribe = received['is_unsubscribe']

                    if 'caller_id' in received:
                        result_caller_id = received['caller_id']

                    contact_updated = Contact.api_update(paid, result_api_token_id, cid, result_firstname,
                                                         result_lastname, result_phonenumber, result_agent_id,
                                                         result_birthday, result_avatar, result_large_avatar,
                                                         result_email, result_address_1, result_address_2, result_city,
                                                         result_state, result_country, result_zip, result_ip,
                                                         result_is_deactivated, result_status,
                                                         result_is_do_not_call, result_is_unsubscribe, result_caller_id)

                    if contact_updated:
                        return contact_updated, 204
                    else:
                        return api.abort(code=400, message="Error updating contact.")
                else:
                    return api.abort(code=400, message="Error updating contact.")
            else:
                return api.abort(404, message='Partnership account not found.')
        else:
            return api.abort(401)


# @ns.route('/<int:paid>/contact/<int:cid>')
@api.doc(responses={200: 'OK',
                    400: 'Error performing operation.',
                    401: 'Unauthorized request.',
                    404: 'Contact not found.'},
         params={'cid': 'The contact Id',
                 'paid': 'The partner account Id'})
class ApiContactGetOne(Resource):
    @requires_auth
    def get(self, paid, cid):
        """
        Retrieves a contact of a partnership account.

        <p>
        The Contacts GET endpoint should be used to return a specific contact for a partner account.
        </p>
        <br />
        <p>
        You require a partner authentication token, a partner account id and contact id to make a successful request. A response will
        be returned, similar to the example below, based
        on a successful request:
        <br />
        <br />
        </p>
         <pre class="code-background" style="color: white">
        {
          "address_1": "10 Main St",
          "address_2": "Apt 2",
          "agent_id": 2,
          "avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
          "birthday": "13 Feb 1984",
          "caller_id": "M Pearson",
          "city": "Chicago",
          "country": "USA",
          "created_on": "2019-09-09 21:11:10",
          "deactivated_on": "",
          "email": "harry@buyercall.com",
          "firstname": "Sue",
          "id": 19,
          "ip": "127.0.4.1",
          "is_deactivated": false,
          "is_do_not_call": false,
          "is_unsubscribe": false,
          "large_avatar": "https://buyercall-logo.s3-us-west-2.amazonaws.com/BuyerCall_Logo.png",
          "lastname": "Pearson",
          "phonenumber": "+17732909657",
          "state": "IL",
          "status": "new lead",
          "updated_on": "2019-09-09 21:13:03",
          "zip": "60613"
        }
        </pre>

        """
        if rest_is_partnership and rest_partnership is not None:
            partnership_account = PartnershipAccount \
                .query \
                .filter(and_(PartnershipAccount.id == paid, PartnershipAccount.partnership_id == rest_partnership.id)) \
                .first()

            if partnership_account is not None:
                contact = Contact.query \
                    .filter(and_(Contact.partnership_account_id == paid, Contact.id == cid)) \
                    .first()

                if contact:
                    response = {
                        'id': contact.id,
                        'created_on': contact.created_datetime,
                        'updated_on': contact.updated_datetime,
                        'firstname': contact.firstname,
                        'lastname': contact.lastname,
                        'phonenumber': contact.phonenumber_1,
                        'agent_id': contact.agent_id,
                        'birthday': contact.birthday,
                        'avatar': contact.avatar,
                        'large_avatar': contact.large_avatar,
                        'email': contact.email,
                        'address_1': contact.address_1,
                        'address_2':  contact.address_2,
                        'city': contact.city,
                        'state': contact.state,
                        'country': contact.country,
                        'zip': contact.zip,
                        'ip': contact.ip,
                        'status': contact.status,
                        'is_do_not_call': contact.is_do_not_call,
                        'is_unsubscribe': contact.is_unsubscribe,
                        'caller_id': contact.caller_id,
                        'is_deactivated': contact.is_deactivated,
                        'deactivated_on': contact.deactivated_on_datetime
                    }

                    from buyercall.blueprints.api2.doc.endpoints.credit_checks import CreditVerification
                    valid_contact, valid_birth_day, error_message = CreditVerification.all_credit_check_fields_exits(contact)

                    if not valid_contact:
                        response['credit_information'] = {
                            'warning': 'Insufficient contact data provided.'
                        }
                    else:
                        try:
                            credit_report_valid, credit_report, error_message = CreditVerification.get_credit_check_report(
                                contact, valid_birth_day)

                            if not credit_report_valid or not credit_report:
                                response['credit_information'] = {
                                    'warning': 'Insufficient contact data provided.'
                                }
                            else:
                                crypto_key = app.config['CRYPTO_SECRET_KEY']
                                cipher = AESCipher(crypto_key)

                                decrypted_score = cipher.decrypt(credit_report.credit_score)
                                converter_score = 0
                                if decrypted_score:
                                    converter_score = int(decrypted_score)

                                decrypted_trades = cipher.decrypt(credit_report.trades)
                                converted_trades = json.loads(decrypted_trades)
                                if 'trades' in converted_trades:
                                    converted_trades = converted_trades['trades']
                                else:
                                    converted_trades = {}

                                response['credit_information'] = {
                                    'approved': credit_report.is_approved,
                                    'score': converter_score,
                                    'trades': converted_trades
                                }
                        except:
                            log.error(
                                "Cannot check credit on contact {}, partnership account {} and got error : {}".format(
                                    contact.id, paid, traceback.format_exc()))
                            response['credit_information'] = {
                                'warning': 'Unable to retrive data.'
                            }

                    return jsonify(
                       response
                    )
                else:
                    return api.abort(404, message='Contact not found.')
            else:
                return api.abort(404, message='Partnership account not found.')
        else:
            return api.abort(401)