""" Booked Vendor Contract Model. Model for getting information about vendor booked contracts. """ from sqlalchemy import Column, Enum, Float, Integer, SmallInteger, Text, and_ from sqlalchemy.exc import SQLAlchemyError from contracts import response from contracts.connectors import mysql, sentry from contracts.constants import error, query class BookedVendorContract(mysql.BaseModel): """Class for booked vendor contract snapshot model.""" __tablename__ = 'booked_vendor_contract_snapshot' snapshot_id = Column( 'contract_snapshot_id', Integer, primary_key=True, autoincrement=True ) contract_id = Column('vendor_contract_id', Integer) period_id = Column(Integer) vendor_id = Column(Integer) payment_interval = Column(Enum(*['month', 'quarter'])) currency_id = Column(Integer) reserve_rate = Column(Float) number_of_months_before_payout = Column(SmallInteger) number_of_installments = Column(SmallInteger) contract_terms = Column(Text) def as_dict(self): """Return object as dict. Returns: dict: Dictionary representation of the object """ contract_dict = { 'id': self.snapshot_id, 'contract_id': self.contract_id, 'period_id': self.period_id, 'vendor_id': self.vendor_id, 'payment_interval': self.payment_interval, 'currency_id': self.currency_id, 'reserve_rate': self.reserve_rate, 'number_of_months_before_payout': self.number_of_months_before_payout, 'number_of_installments': self.number_of_installments, 'contract_terms': self.contract_terms, } return contract_dict def get_booked_contracts( vendor_id, sort_order=query.DESC, page_limit=query.PAGE_LIMIT_DEFAULT, page_offset=query.PAGE_OFFSET_DEFAULT, ): """Get all booked contracts for provided vendor_id. Args: vendor_id (int): Vendor Id. sort_order (str): Order of sorting: asc or desc. page_limit (int): Count of records to fetch. page_offset (int): count of records to skip. Returns: response.Response: List of booked contracts or error in Response object. """ try: filters = [BookedVendorContract.vendor_id == vendor_id] sort = BookedVendorContract.period_id if sort_order == query.ASC: sort = sort.asc() else: sort = sort.desc() with mysql.db_session(False) as session: contracts = ( session.query(BookedVendorContract) .filter(*filters) .order_by(sort) .offset(page_offset) .limit(page_limit) .all() ) if not contracts: return response.create_not_found_response( error.ERROR_MESSAGE_BOOKED_CONTRACTS_NOT_FOUND ) return response.Response(contracts) except SQLAlchemyError as ex: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(str(ex)) def get_booked_contracts_count(vendor_id): """Return count of booked contracts for provided vendor_id. Args: vendor_id (int): Vendor Id. Returns: response.Response: response with count of vendor booked contracts. """ try: with mysql.db_session(False) as session: contracts_count = ( session.query(BookedVendorContract) .filter_by(vendor_id=vendor_id) .count() ) return response.Response(contracts_count) except SQLAlchemyError as ex: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(str(ex)) def get_booked_contracts_by_period_range( vendor_id, first_period, last_period, sort_order=query.DESC ): """Return booked contrats by a period range. Args: vendor_id (int): Vendor Id first_period (int): The first period of the range last_period (int): The last period of the range sort_order (str): Order of sorting: asc or desc. Returns: response.Response: List of booked contracts or error in Response object. """ try: filters = [ and_( BookedVendorContract.vendor_id == vendor_id, BookedVendorContract.period_id.between(first_period, last_period), ) ] sort = BookedVendorContract.period_id if sort_order == query.ASC: sort = sort.asc() else: sort = sort.desc() with mysql.db_session(False) as session: contracts = ( session.query(BookedVendorContract) .filter(*filters) .order_by(sort) .all() ) if not contracts: return response.create_not_found_response( error.ERROR_MESSAGE_BOOKED_CONTRACTS_NOT_FOUND ) result = [item.as_dict() for item in contracts] return response.Response(result) except SQLAlchemyError as ex: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response(str(ex))