""" Product Territory Split Model. Model for getting information about product territory split. """ from sqlalchemy import ( BigInteger, Column, Float, ForeignKey, Index, Integer, SmallInteger, exc as sqlexeption, ) from sqlalchemy.orm import relationship from contracts import response from contracts.connectors import mysql from contracts.constants import contracts_constants, error from contracts.models import contract_history from contracts.models.country import Country # noqa F401 class ProductTerritorySplit(mysql.BaseModel): """ProductTerritorySplit class.""" __tablename__ = 'product_territory_split' __table_args__ = ( Index('uidx_prod_territory', 'product_id', 'country_id', unique=True), ) product_territory_split_id = Column(Integer, primary_key=True) vendor_id = Column(SmallInteger, nullable=False) product_id = Column(BigInteger, nullable=False) country_id = Column( ForeignKey('country.id', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, index=True, ) split_rate = Column(Float, nullable=False) country = relationship('Country', lazy='joined') def to_dict(self): """Get a dict representation.""" return { 'upc': self.product_id, 'vendor_id': self.vendor_id, 'product_territory_split': self.split_rate, 'country_details': self.country.to_dict(), } def set_product_territory_split(data, vendor_id): """Set a product territory split for provided upc and country id. Args: upc (int): unique product code data (list): a list of dictionaries of request parameters. Returns: response.Response: status """ with mysql.db_session() as session: for item in data: product_territory_split = ProductTerritorySplit( vendor_id=vendor_id, product_id=item['upc'], country_id=item['country_id'], split_rate=item['split_rate'], ) vendor_history = contract_history.set_product_territory_change_history( contracts_constants.SET_PRODUCT_TERRITORY_SPLIT_MESSAGE, item['upc'], item['country_id'], item['vend_contract_id'], item['oa_user_id'], item['country_name'], item['split_rate'], ) try: session.add(product_territory_split) session.add(vendor_history) session.flush() except sqlexeption.IntegrityError: session.rollback() return response.create_error_response( 'Conflict', 'Duplicate entry for upc and country id', 409 ) session.commit() return response.create_status_ok_response() def update_product_territory_split(data): """Update a product territory split for provided country_id and upc. Args: data (list): a list of dictionaries of request parameters. Returns: response.Response: status """ with mysql.db_session() as session: for item in data: row = ( session.query(ProductTerritorySplit) .filter(ProductTerritorySplit.product_id == item['upc']) .filter(ProductTerritorySplit.country_id == item['country_id']) .first() ) if not row: return response.create_not_found_response('Country ID not found') row.split_rate = item['split_rate'] vendor_history = contract_history.set_product_territory_change_history( contracts_constants.UPDATE_PRODUCT_TERRITORY_SPLIT_MESSAGE, item['upc'], item['country_id'], item['vend_contract_id'], item['oa_user_id'], item['country_name'], item['split_rate'], item['old_split_rate'], ) try: session.add(vendor_history) session.flush() except sqlexeption.IntegrityError: session.rollback() session.commit() return response.create_status_ok_response() def get_product_territory_split(vendor_id, page_offset=None, page_limit=None): """Get a product territory splits for provided vendor. Args: vendor_id (int): Vendor Id. Returns: response.Response: list of upcs, country details and product territory splits """ sort = ProductTerritorySplit.product_territory_split_id with mysql.db_session() as session: query = ( session.query(ProductTerritorySplit) .filter(ProductTerritorySplit.vendor_id == vendor_id) .order_by(sort.desc()) ) paginated_query = query.offset(page_offset).limit(page_limit) result = [splits.to_dict() for splits in paginated_query.all()] session.expunge_all() result_data = { 'items': result, 'pagination': { 'type': 'standard', 'offset': page_offset, 'limit': page_limit, 'total_records': query.count(), }, } return response.Response(result_data) def delete_product_territory_split(upc, data): """Delete a product territoty split for provided UPC and country id. Args: UPC: unique product code. data (dict): dictionary of request parameters. Returns: response.Response: status """ with mysql.db_session() as session: row = ( session.query(ProductTerritorySplit) .filter( ProductTerritorySplit.product_id == upc, ProductTerritorySplit.country_id == data['country_id'], ) .first() ) if not row: return response.create_not_found_response( error.ERROR_MESSAGE_PRODUCT_TERRITORY_SPLIT_RECORD_NOT_FOUND.format( country_id=data['country_id'], upc=upc ) ) session.delete(row) vendor_history = contract_history.set_product_territory_change_history( contracts_constants.DELETE_PRODUCT_TERRITORY_SPLIT_MESSAGE, upc, data['country_id'], data['vend_contract_id'], data['oa_user_id'], data['country_name'], ) session.add(vendor_history) session.commit() return response.create_status_ok_response()