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/block_numbers/models.py
from collections import OrderedDict
import logging
from sqlalchemy import or_, and_
from sqlalchemy.sql import text
from buyercall.lib.util_sqlalchemy import ResourceMixin
from buyercall.extensions import db


log = logging.getLogger(__name__)


class Block(ResourceMixin, db.Model):
    STATUS = OrderedDict([
        ('blocked', 'Blocked'),
        ('unblocked', 'Unblocked')
    ])

    __tablename__ = 'block_numbers'

    id = db.Column(db.Integer, primary_key=True)

    # Partnership account id.
    partnership_accounts_id = db.Column(
        db.Integer,
        db.ForeignKey(
            'partnership_accounts.id',
            onupdate='CASCADE',
            ondelete='CASCADE'
        ),
        index=True,
        nullable=False
    )

    status = db.Column(db.Enum(*STATUS.keys(), name='block_states'),
                       index=True, nullable=False, server_default='blocked')
    # Phone numbers.
    phonenumber = db.Column(db.String(20), nullable=False,
                            server_default='')
    # Use to exclude phone numbers from all accounts if set true
    global_exclusion = db.Column('is_global_exclusion', db.Boolean(), nullable=False, server_default='0')

    @classmethod
    def search(cls, query):
        """
        Search a resource by 1 or more fields.

        :param query: Search query
        :type query: str
        :return: SQLAlchemy filter
        """
        if not query:
            return text('')

        search_query = '%{0}%'.format(query)

        return text(or_(Block.phonenumber.ilike(search_query)))

    @classmethod
    def blocked(cls, inbound_id, phonenumber):
        # Get the BuyerCall phone number in question
        from ..phonenumbers.models import Phone
        inbound = Phone.query.filter(Phone.id == inbound_id).first()
        # Check if the phone number is on the blocked list of numbers
        filter_by_block = cls.partnership_accounts_id == inbound.partnership_account_id
        blocked_numbers = cls.query.filter(or_(filter_by_block, cls.global_exclusion.is_(True))) \
            .filter(cls.status == 'blocked').all()

        blocked_number_list = []

        for number in blocked_numbers:
            from ..filters import format_phone_number
            formatted_pn = format_phone_number(number.phonenumber)
            blocked_number_list.append(formatted_pn)
        # If the phone number is in the list of blocked numbers then return True otherwise False
        if phonenumber in blocked_number_list:
            return True
        else:
            return False

    @classmethod
    def create(cls, params):
        """
        Return whether or not the blocked number was created successfully.

        :return: bool
        """
        block_number_params = params

        block_number = Block(**block_number_params)

        db.session.add(block_number)
        db.session.commit()

        return True

    @classmethod
    def api_create(cls, params):
        """
        Return blocked number id if created successfully.

        :return: blocked number id
        """
        block_id = -1
        block_number_params = params

        block_number = Block(**block_number_params)

        db.session.add(block_number)
        db.session.flush()

        block_id = block_number.id

        db.session.commit()

        return block_id

    @classmethod
    def update(cls, id, partnership_accounts_id, status, phonenumber, global_exclusion):
        """
        Return whether or not the blocked number was updated successfully.

        :return: bool
        """
        block_number = db.session.query(Block).filter(and_(Block.id == id, Block.partnership_accounts_id == partnership_accounts_id)).first()

        if block_number is not None:
            block_number.phonenumber = phonenumber
            block_number.global_exclusion = global_exclusion
            converted_status = status.lower()

            if converted_status not in ['blocked', 'unblocked']:
                block_number.status = 'blocked'
            else:
                block_number.status = converted_status
            db.session.commit()
            return True
        else:
            return False

    @classmethod
    def api_update(cls, id, partnership_accounts_id, status, phonenumber, global_exclusion):
        """
        Return whether or not the blocked number was updated successfully.

        :return: bool
        """
        block_number = db.session.query(Block)\
            .filter(and_(Block.id == id, Block.partnership_accounts_id == partnership_accounts_id))\
            .first()

        if block_number is not None:

            if status is not None:
                block_number.status = status

            if phonenumber is not None:
                block_number.phonenumber = phonenumber

            if global_exclusion is not None:
                block_number.global_exclusion = global_exclusion

            db.session.commit()

            return True
        else:
            return False