Rev 1347 | Rev 1399 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
'''Created on 23-Mar-2010@author: ashish'''from elixir import *from shop2020.model.v1.catalog.impl import DataServicefrom shop2020.model.v1.catalog.impl.DataService import Item, \Warehouse, ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo,\ItemChangeLog, Category, EntityIDGenerator, VendorItemPricing,\VendorItemMappingfrom shop2020.thriftpy.model.v1.catalog.ttypes import \InventoryServiceException, statusfrom shop2020.model.v1.catalog.impl.Convertors import to_t_itemimport datetimeimport sysfrom shop2020.utils.Utils import log_entry, to_py_datefrom sqlalchemy import desc, ascdef initialize():DataService.initialize()def get_all_items(is_active):if is_active:items = Item.query.filter_by(status= status.ACTIVE).all()else:items = Item.query.all()return itemsdef get_all_items_by_status(status):if not status:#return all itemsitems = get_all_items(False)else:items = Item.query.filter_by(status=status).all()return itemsdef get_item(item_id):item = Item.get_by(id=item_id)return itemdef get_items_by_catalog_id(catalog_id):query = Item.query.filter_by(catalog_item_id=catalog_id)try:items = query.all()return get_thrift_item_list(items)except:raise InventoryServiceException(109, "Item not found")def is_active(item_id):try:item = get_item(item_id)return item.status == status.ACTIVEexcept InventoryServiceException:return Falsedef get_Warehouse(warehouse_id):return Warehouse.get_by(id=warehouse_id)def get_all_warehouses_by_status(status):if not status:warehouses = Warehouse.query.all()else:warehouses = Warehouse.query.filter_by(status=status).all()return warehousesdef get_all_warehouses_for_item(item_id):item = get_item(item_id)if not item:raise InventoryServiceException(108, "Some unforeseen error while obtaining item")return item.get_all_warehousesdef get_all_items_for_warehouse(warehouse_id):warehouse = get_Warehouse(warehouse_id)if not warehouse:raise InventoryServiceException(108, "bad warehouse")return warehouse.all_itemsdef add_warehouse(warehouse):if not warehouse:raise InventoryServiceException(108, "Bad warehouse")if get_Warehouse(warehouse.id):#warehouse is already present.raise InventoryServiceException(101, "Warehouse already present")ds_warehouse = Warehouse()ds_warehouse.id = warehouse.idds_warehouse.location = warehouse.locationds_warehouse.status = status.ACTIVEds_warehouse.addedOn = datetime.datetime.now()ds_warehouse.lastCheckedOn = datetime.datetime.now()ds_warehouse.tinNumber = warehouse.tinNumberds_warehouse.pincode = warehouse.pincodeif warehouse.vendorString:ds_warehouse.vendorString = warehouse.vendorStringsession.commit()return ds_warehouse.iddef update_item(item):if not item:raise InventoryServiceException(108, "Bad item in request")if not item.id:raise InventoryServiceException(101, "Missing id for update")ds_item = get_item(item.id)if not ds_item:raise InventoryServiceException(101, "Item missing in our database")if item.productGroup:ds_item.product_group = item.productGroupif item.brand:ds_item.brand = item.brandif item.modelName:ds_item.model_name = item.modelNameif item.modelNumber:ds_item.model_number = item.modelNumberif item.color:ds_item.color = item.colorif item.category:ds_item.category = item.categoryif item.comments:ds_item.comments = item.commentsif item.catalogItemId:ds_item.catalog_item_id = item.catalogItemIdif item.mrp:ds_item.mrp = item.mrpif item.mop:ds_item.mop = item.mopif item.sellingPrice:ds_item.sellingPrice = item.sellingPriceif item.dealerPrice:ds_item.dealerPrice = item.dealerPriceif item.weight:ds_item.weight = item.weightif item.itemStatus:ds_item.status = item.itemStatusif item.startDate:ds_item.startDate = item.startDateif item.retireDate:ds_item.retireDate = item.retireDateif item.featureId:ds_item.feature_id = item.featureIdif item.featureDescription:ds_item.feature_description = item.featureDescriptionif item.bestDealText:ds_item.bestDealText = item.bestDealTextif item.bestDealValue:ds_item.bestDealValue = item.bestDealValueds_item.updated_on = datetime.datetime.now()session.commit();return ds_item.iddef add_item(item):if not item:raise InventoryServiceException(108, "Bad item in request")if get_item(item.id):raise InventoryServiceException(101, "Item already exists")ds_item = Item()if item.id:ds_item.id = item.idif item.productGroup:ds_item.product_group = item.productGroupif item.brand:ds_item.brand = item.brandif item.modelName:ds_item.model_name = item.modelNameif item.modelNumber:ds_item.model_number = item.modelNumberif item.color:ds_item.color = item.colorif item.category:ds_item.category = item.categoryif item.comments:ds_item.comments = item.commentsif item.catalogItemId:ds_item.catalog_item_id = item.catalogItemIdif item.itemStatus:ds_item.status = item.itemStatuselse: #this is for update callsds_item.status = status.IN_PROCESSds_item.addedOn = datetime.datetime.now()ds_item.updatedOn = datetime.datetime.now()if item.mrp:ds_item.mrp = item.mrpif item.mop:ds_item.mop = item.mopif item.sellingPrice:ds_item.sellingPrice = item.sellingPriceif item.dealerPrice:ds_item.dealerPrice = item.dealerPriceif item.weight:ds_item.weight = item.weightif item.featureId:ds_item.feature_id = item.featureIdif item.featureDescription:ds_item.feature_description = item.featureDescriptionif item.otherInfo:for k,v in item.otherInfo.iteritems():info = ItemInfo()info.key = kinfo.value = vds_item.iteminfo.append(info)#check if categories present. If yes, add them to systemif item.bestDealValue:ds_item.bestDealValue = item.bestDealValueif item.bestDealText:ds_item.bestDealText = item.bestDealTextsession.commit();return ds_item.iddef update_inventory(warehouse_id, timestamp, availability):warehouse = get_Warehouse(warehouse_id)if not warehouse:raise InventoryServiceException(107, "Warehouse? Where?")time = datetime.datetime.now()warehouse.lastCheckedOn = timewarehouse.vendorString = timestampvendor = warehouse.vendorfor item_key, quantity in availability.iteritems():try:vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();item = vendor_item_mapping.itemexcept:continuetry:item_inventory_history = ItemInventoryHistory()item_inventory_history.warehouse = warehouseitem_inventory_history.item = itemitem_inventory_history.timestamp = timeitem_inventory_history.availibility = quantitycurrent_inventory_snapshot = CurrentInventorySnapshot.get_by(item=item, warehouse=warehouse)if not current_inventory_snapshot:current_inventory_snapshot = CurrentInventorySnapshot()current_inventory_snapshot.item = itemcurrent_inventory_snapshot.warehouse = warehousecurrent_inventory_snapshot.availibility = 0current_inventory_snapshot.reserved = 0# added the difference in the current inventorycurrent_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantityexcept:raise InventoryServiceException(108, "Some unforeseen error while updating inventory")session.commit()def get_item_inventoy(item_id):inventory = Item.get_by(id=item_id).currentInventoryif not inventory:raise InventoryServiceException(108, "Some unforeseen error while updating inventory")return inventorydef get_item_inventory_by_item_id(item_id):inventory = Item.get_by(id=item_id).currentInventoryif not inventory:raise InventoryServiceException(108, "Some unforeseen error while updating inventory")return inventorydef retire_warehouse(warehouse_id):if not warehouse_id:raise InventoryServiceException(101, "Bad warehouse id")warehouse = get_Warehouse(warehouse_id)if not warehouse:raise InventoryServiceException(108, "warehouse id not present")warehouse.status = status.DELETED;session.commit()def retire_item(item_id):if not item_id:raise InventoryServiceException(101, "bad item id")item = get_item(item_id)if not item:raise InventoryServiceException(108, "item id not present")item.status = status.PHASED_OUTitem.retireDate = datetime.datetime.now()session.commit()#need to implement threads based solution heredef start_item_on(item_id, timestamp):if not item_id:raise InventoryServiceException(101, "bad item id")item = get_item(item_id)if not item:raise InventoryServiceException(108, "item id not present")item.status = status.ACTIVEitem.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))add_status_change_log(item, status.ACTIVE)session.commit()#need to implement threads heredef retire_item_on(item_id, timestamp):if not item_id:raise InventoryServiceException(101, "bad item id")item = get_item(item_id)if not item:raise InventoryServiceException(108, "item id not present")item.status = status.PHASED_OUTitem.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))add_status_change_log(item, status.PHASED_OUT)session.commit()def add_status_change_log(item, new_status):item_change_log = ItemChangeLog()item_change_log.new_status = new_statusitem_change_log.old_status = item.statusitem_change_log.timestamp = datetime.datetime.now()item_change_log.item = itemsession.commit()def change_item_status(item_id, new_status):if not item_id:raise InventoryServiceException(101, "bad item id")item = get_item(item_id)if not item:raise InventoryServiceException(108, "item id not present")item.status = new_statusadd_status_change_log(item, new_status)session.commit()def get_item_availability_for_warehouse(warehouse_id, item_id):if not warehouse_id:raise InventoryServiceException(101, "bad warehouse_id")if not item_id:raise InventoryServiceException(101, "bad item_id")warehouse = get_Warehouse(warehouse_id)if not warehouse:raise InventoryServiceException(108, "warehouse does not exist")item = get_item(item_id)if not item:raise InventoryServiceException(108, "item does not exist")query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)query = query.filter_by(item_id = item.id)try:current_inventory_snapshot = query.one()return current_inventory_snapshot.availibility - current_inventory_snapshot.reservedexcept:return 0"""current_inventory_snapshot = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id == warehouse_id, CurrentInventorySnapshot.item_id == item_id).one()if not current_inventory_snapshot:return 0else:return current_inventory_snapshot.availibility"""def reserve_item_in_warehouse(item_id, warehouse_id, quantity):if not warehouse_id:raise InventoryServiceException(101, "bad warehouse_id")if not item_id:raise InventoryServiceException(101, "bad item_id")query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)try:current_inventory_snapshot = query.one()current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantitysession.commit()return Trueexcept:print "Unexpected error:", sys.exc_info()[0]return Falsedef reduce_reservation_count(item_id, warehouse_id, quantity):if not warehouse_id:raise InventoryServiceException(101, "bad warehouse_id")if not item_id:raise InventoryServiceException(101, "bad item_id")query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)try:current_inventory_snapshot = query.one()current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantitysession.commit()return Trueexcept:print "Unexpected error:", sys.exc_info()[0]return Falsedef mark_item_as_content_complete(entity_id):content_complete_status = status.CONTENT_COMPLETEitems = Item.query.filter_by(catalog_item_id=entity_id, status=status.IN_PROCESS).all()current_timestamp = datetime.datetime.now()for item in items:item_change_log = ItemChangeLog()item_change_log.old_status = item.statusitem_change_log.new_status = content_complete_statusitem_change_log.timestamp = current_timestampitem_change_log.item = itemitem.status = content_complete_statusitem.updatedOn = current_timestampsession.commit()return Truedef get_item_availability_for_location(warehouse_loc, item_id):if warehouse_loc is None:raise InventoryServiceException(101, "Bad Warehouse Location")if not item_id:raise InventoryServiceException(101, "Bas Item id")warehouses = Warehouse.query.filter_by(logisticsLocation=warehouse_loc).all()warehouse_ids = [warehouse.id for warehouse in warehouses]warehouse_retid = -1global_availability = 0for warehouse_id in warehouse_ids:try:current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reservedexcept:availability = 0if availability > global_availability:warehouse_retid = warehouse_idglobal_availability = availabilityif warehouse_retid == -1:# This is the case when all warehouses have exhausted their# inventory of this item or no warehouse is available in this# location.#TODO: Change 1 to be a constant read from the Config client.warehouse_retid = 1return [warehouse_retid, global_availability]def get_warehouses_for_item(item_id):if not item_id:raise InventoryServiceException(101, "bad item_id")item = get_item(item_id)if not item:raise InventoryServiceException(101, "bad item")warehouses = item.currentInventory.warehousereturn warehousesdef get_best_sellers(start_index, stop_index, category=-1):query = get_best_sellers_query(category)best_sellers = query.all()[start_index:stop_index]return get_thrift_item_list(best_sellers)def get_best_sellers_count(category):count = get_best_sellers_query(category).count()if count is None:count = 0return countdef get_best_sellers_catalog_ids(start_index, stop_index, category=-1):query = get_best_sellers_query(category)best_sellers = query.all()[start_index:stop_index]return [item.catalog_item_id for item in best_sellers]def get_best_sellers_query(category):query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)if category != -1:query = query.filter_by(category=category)query = query.order_by(asc(Item.bestSellingRank))return querydef get_best_deals(category=-1):query = get_best_deals_query(category)items = query.all()return get_thrift_item_list(items)def get_best_deals_count(category=-1):count = get_best_deals_query(category).count()if count is None:count = 0return countdef get_best_deals_catalog_ids(start_index, stop_index, category=-1):query = get_best_deals_query(category)best_deal_items = query.all()[start_index:stop_index]return [item.catalog_item_id for item in best_deal_items]def get_best_deals_query(category):query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)if category != -1:query = query.filter_by(category=category)query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))return querydef get_latest_arrivals(limit, category=-1):query = get_latest_arrivals_query(category)items = query.all()[0:limit]return get_thrift_item_list(items)def get_latest_arrivals_count(limit, category=-1):count = get_latest_arrivals_query(category).count()if count is None:count = 0count = min(count, limit)return countdef get_latest_arrivals_catalog_ids(start_index, stop_index, category=-1):query = get_latest_arrivals_query(category)latest_arrivals = query.all()[start_index:stop_index]return [item.catalog_item_id for item in latest_arrivals]def get_latest_arrivals_query(category):query = Item.query.filter_by(status=status.ACTIVE)if category != -1:query = query.filter_by(category=category)query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate))return querydef get_thrift_item_list(items):return [to_t_item(item) for item in items if item != None]def generate_new_entity_id():generator = EntityIDGenerator.query.one()id = generator.id + 1generator.id = idsession.commit()return iddef put_category_object(object):category = Category.get_by(id=1)if category is None:category = Category()category.object = objectsession.commit()return Truedef get_category_object():object = Category.get_by(id=1).objectreturn objectdef get_item_pricing(item_id, warehouse_id):item = Item.query.filter_by(id=item_id).first()if item is None:raise InventoryServiceException(101, "Bad Item")warehouse = get_Warehouse(warehouse_id)if not warehouse:raise InventoryServiceException(108, "Bad Warehouse")vendor = warehouse.vendortry:item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item=item).one()return item_pricingexcept sqlalchemy.orm.exc.MultipleResultsFound:raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))except sqlalchemy.orm.exc.NoResultFound:raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))def close_session():if session.is_active:print "session is active. closing it."session.close()