"""Product Live Time Model CRUD operation.""" from oto import response from sqlalchemy import Column, Enum, Integer, Time from timed_release import config from timed_release.connectors import sql from timed_release.constants import error, success from timed_release.models.product_store import ProductStore class ProductLiveTime(sql.base_model): """Table definition for product_live_time table.""" __tablename__ = 'product_live_time' product_id = Column( 'product_id', Integer, primary_key=True, nullable=False) time_of_day_product = Column(Time, nullable=False) time_zone = Column(Enum(*config.TIME_ZONES), nullable=False) def to_dict(self): """Return a dictionary of a product_live_time.""" return { 'product_id': self.product_id, 'time_of_day_product': str(self.time_of_day_product), 'time_zone': self.time_zone } @sql.wrap_db_errors def delete_product_live_time_details(product_id): """Delete product live time details by product id. Args: product_id (int): Product id to delete product live time details. Returns: response.Response: Response containing delete success message or error response message. """ with sql.db_session() as session: affected_row_count = session.query(ProductLiveTime).filter( ProductLiveTime.product_id == product_id).delete() if not affected_row_count: return response.create_not_found_response( error.ERROR_MESSAGE_PRODUCT_NOT_FOUND.format(product_id)) return response.Response( message=success.DELETE_SUCCESS_MESSAGE_TIMED_RELEASE) @sql.wrap_db_errors def update_product_live_time_details_with_stores(product_id, data): """Update product live time details of release time and stores. Args: product_id (int): Unique identification for product. data (dict): Dict having timed release data and stores. Returns: response.Response: Response dict of inserted product live time details or error. """ timed_release_data = { 'product_id': product_id, 'time_of_day_product': data['time_of_day_product'], 'time_zone': data['time_zone']} store_ids = data['store_ids'] with sql.db_session() as session: affected_row_count = session.query(ProductLiveTime).filter( ProductLiveTime.product_id == product_id).update( timed_release_data) if not affected_row_count: return response.create_not_found_response( error.ERROR_MESSAGE_PRODUCT_NOT_FOUND.format(product_id)) session.query(ProductStore).filter( ProductStore.product_id == product_id).delete() store_ids = list(set(store_ids)) product_store_data = [ ProductStore(product_id=product_id, store_id=store_id) for store_id in store_ids] session.bulk_save_objects(product_store_data) return response.Response( message=success.UPDATE_SUCCESS_MESSAGE.format(product_id)) @sql.wrap_db_errors def create_product_live_time_details_with_stores( product_id, time_of_day_product, time_zone, store_ids=None): """Create product live time details of release time and stores. Args: product_id (int): Unique identification for product. time_of_day_product (str): Time to product go live. time_zone (str): Time Zone to product go live. store_ids (list): List of unique DMS ids. Returns: response.Response: Response dict of inserted product live time details or error. """ timed_release_data = { 'product_id': product_id, 'time_of_day_product': time_of_day_product, 'time_zone': time_zone} product_store_data = [] with sql.db_session() as session: timed_release_data_to_add = ProductLiveTime(**timed_release_data) session.add(timed_release_data_to_add) session.flush() store_ids = list(set(store_ids)) product_store_data = [ ProductStore(product_id=product_id, store_id=store_id) for store_id in store_ids] session.bulk_save_objects(product_store_data) timed_release_data['store_ids'] = store_ids return response.Response(message={'product': timed_release_data}) @sql.wrap_db_errors def get_product_live_time_details_and_stores(product_id): """ Get all information of product live time and stores for given product id. Args: product_id (int): Product id to fetch product live time details. Return: response: message containing data upon successful query. error Response message otherwise. """ with sql.db_session() as session: result_set = session.query( ProductLiveTime.product_id.label('product_id'), ProductLiveTime.time_of_day_product.label('time_of_day_product'), ProductLiveTime.time_zone.label('time_zone'), ProductStore.store_id.label('store_id') ).join( ProductStore, ProductLiveTime.product_id == ProductStore.product_id ).filter( ProductLiveTime.product_id == product_id ).all() if not result_set: return response.create_not_found_response( error.ERROR_MESSAGE_PRODUCT_NOT_FOUND.format(product_id)) store_ids = [row.store_id for row in result_set] product_live_time = { 'product_id': result_set[0].product_id, 'time_of_day_product': str(result_set[0].time_of_day_product), 'time_zone': result_set[0].time_zone, 'store_ids': store_ids} return response.Response(message=product_live_time)