| Line 39... |
Line 39... |
| 39 |
|
39 |
|
| 40 |
to_addresses = ["cnc.center@shop2020.in", "ashutosh.saxena@shop2020.in"]
|
40 |
to_addresses = ["cnc.center@shop2020.in", "ashutosh.saxena@shop2020.in"]
|
| 41 |
from_user = "cnc.center@shop2020.in"
|
41 |
from_user = "cnc.center@shop2020.in"
|
| 42 |
from_pwd = "5h0p2o2o"
|
42 |
from_pwd = "5h0p2o2o"
|
| 43 |
|
43 |
|
| 44 |
def initialize():
|
44 |
item_availability_cache = {}
|
| - |
|
45 |
|
| - |
|
46 |
def initialize(dbname='catalog', db_hostname="localhost"):
|
| 45 |
DataService.initialize()
|
47 |
DataService.initialize(dbname, db_hostname)
|
| 46 |
|
48 |
|
| 47 |
def get_all_items_by_status(status, offset=0, limit=None):
|
49 |
def get_all_items_by_status(status, offset=0, limit=None):
|
| 48 |
query = Item.query
|
50 |
query = Item.query
|
| 49 |
if status is not None:
|
51 |
if status is not None:
|
| 50 |
query = query.filter_by(status=status)
|
52 |
query = query.filter_by(status=status)
|
| Line 434... |
Line 436... |
| 434 |
if current_inventory_snapshot.availibility < 0:
|
436 |
if current_inventory_snapshot.availibility < 0:
|
| 435 |
__send_alert_for_negative_availability(item, current_inventory_snapshot.availibility, warehouse)
|
437 |
__send_alert_for_negative_availability(item, current_inventory_snapshot.availibility, warehouse)
|
| 436 |
except:
|
438 |
except:
|
| 437 |
raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
|
439 |
raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
|
| 438 |
session.commit()
|
440 |
session.commit()
|
| - |
|
441 |
#**Update item availability cache**#
|
| - |
|
442 |
__update_item_availability_cache(item.id)
|
| 439 |
check_risky_item(item)
|
443 |
check_risky_item(item)
|
| 440 |
|
444 |
|
| 441 |
def __send_alert_for_negative_reserved(item, reserved, warehouse):
|
445 |
def __send_alert_for_negative_reserved(item, reserved, warehouse):
|
| 442 |
itemName = " ".join([str(item.id), str(item.brand), str(item.model_name), str(item.model_number), str(item.color)])
|
446 |
itemName = " ".join([str(item.id), str(item.brand), str(item.model_name), str(item.model_number), str(item.color)])
|
| 443 |
EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'mandeep.dhir@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
|
447 |
EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'mandeep.dhir@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
|
| Line 471... |
Line 475... |
| 471 |
current_inventory_snapshot.availibility = 0
|
475 |
current_inventory_snapshot.availibility = 0
|
| 472 |
current_inventory_snapshot.reserved = 0
|
476 |
current_inventory_snapshot.reserved = 0
|
| 473 |
# added the difference in the current inventory
|
477 |
# added the difference in the current inventory
|
| 474 |
current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
|
478 |
current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
|
| 475 |
session.commit()
|
479 |
session.commit()
|
| - |
|
480 |
#**Update item availability cache**#
|
| - |
|
481 |
__update_item_availability_cache(itemId)
|
| 476 |
if current_inventory_snapshot.availibility < 0:
|
482 |
if current_inventory_snapshot.availibility < 0:
|
| 477 |
__send_alert_for_negative_availability(get_item(itemId), current_inventory_snapshot.availibility, get_Warehouse(warehouseId))
|
483 |
__send_alert_for_negative_availability(get_item(itemId), current_inventory_snapshot.availibility, get_Warehouse(warehouseId))
|
| 478 |
check_risky_item(get_item(itemId))
|
484 |
check_risky_item(get_item(itemId))
|
| 479 |
|
485 |
|
| 480 |
def add_bad_inventory(itemId, warehouseId, quantity):
|
486 |
def add_bad_inventory(itemId, warehouseId, quantity):
|
| Line 672... |
Line 678... |
| 672 |
current_inventory_snapshot.availibility = 0
|
678 |
current_inventory_snapshot.availibility = 0
|
| 673 |
current_inventory_snapshot.reserved = 0
|
679 |
current_inventory_snapshot.reserved = 0
|
| 674 |
|
680 |
|
| 675 |
current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
|
681 |
current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
|
| 676 |
session.commit()
|
682 |
session.commit()
|
| - |
|
683 |
#**Update item availability cache**#
|
| - |
|
684 |
__update_item_availability_cache(item_id)
|
| 677 |
check_risky_item(item)
|
685 |
check_risky_item(item)
|
| 678 |
return True
|
686 |
return True
|
| 679 |
|
687 |
|
| 680 |
def reduce_reservation_count(item_id, warehouse_id, quantity):
|
688 |
def reduce_reservation_count(item_id, warehouse_id, quantity):
|
| 681 |
if not warehouse_id:
|
689 |
if not warehouse_id:
|
| Line 687... |
Line 695... |
| 687 |
query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
|
695 |
query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
|
| 688 |
try:
|
696 |
try:
|
| 689 |
current_inventory_snapshot = query.one()
|
697 |
current_inventory_snapshot = query.one()
|
| 690 |
current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
|
698 |
current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
|
| 691 |
session.commit()
|
699 |
session.commit()
|
| - |
|
700 |
#**Update item availability cache**#
|
| - |
|
701 |
__update_item_availability_cache(item_id)
|
| 692 |
check_risky_item(item)
|
702 |
check_risky_item(item)
|
| 693 |
if current_inventory_snapshot.reserved < 0:
|
703 |
if current_inventory_snapshot.reserved < 0:
|
| 694 |
__send_alert_for_negative_reserved(get_item(item_id), current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
|
704 |
__send_alert_for_negative_reserved(get_item(item_id), current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
|
| 695 |
return True
|
705 |
return True
|
| 696 |
except:
|
706 |
except:
|
| Line 723... |
Line 733... |
| 723 |
item.model_number = modelNumber
|
733 |
item.model_number = modelNumber
|
| 724 |
item.updatedOn = current_timestamp
|
734 |
item.updatedOn = current_timestamp
|
| 725 |
session.commit()
|
735 |
session.commit()
|
| 726 |
return True
|
736 |
return True
|
| 727 |
|
737 |
|
| 728 |
def get_item_availability_for_location(warehouse_loc, item_id):
|
738 |
def get_item_availability_for_location(item_id):
|
| - |
|
739 |
if item_availability_cache.has_key(item_id):
|
| - |
|
740 |
return item_availability_cache[item_id]
|
| - |
|
741 |
__update_item_availability_cache(item_id)
|
| - |
|
742 |
return item_availability_cache[item_id]
|
| - |
|
743 |
|
| - |
|
744 |
def __cache_item_availability():
|
| - |
|
745 |
items = Item.query.filter(Item.status.in_((status.ACTIVE, status.COMING_SOON, status.PAUSED, status.PAUSED_BY_RISK))).all()
|
| - |
|
746 |
for item in items:
|
| - |
|
747 |
__update_item_availability_cache(item.id)
|
| - |
|
748 |
|
| - |
|
749 |
def __update_item_availability_cache(item_id):
|
| 729 |
"""
|
750 |
"""
|
| 730 |
Determines the warehouse that should be used to fulfil an order for the given item.
|
751 |
Determines the warehouse that should be used to fulfil an order for the given item.
|
| 731 |
Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
|
752 |
Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
|
| 732 |
|
753 |
|
| 733 |
If item's Preferred warehouse is present
|
754 |
If item's Preferred warehouse is present
|
| Line 751... |
Line 772... |
| 751 |
else
|
772 |
else
|
| 752 |
use ThirdPartyWarehouse without billing support with maximum availability
|
773 |
use ThirdPartyWarehouse without billing support with maximum availability
|
| 753 |
|
774 |
|
| 754 |
Returns an ordered list of size 4 with following elements in the given order:
|
775 |
Returns an ordered list of size 4 with following elements in the given order:
|
| 755 |
1. Logistics location of the warehouse which was finally picked up to ship the order.
|
776 |
1. Logistics location of the warehouse which was finally picked up to ship the order.
|
| 756 |
2. Id of the warehouse which was finally picked up.
|
- |
|
| 757 |
3. Inventory size in the selected warehouse.
|
777 |
2. Expected delay added by the category manager.
|
| 758 |
4. Expected delay added by the category manager.
|
778 |
3. Id of the warehouse which was finally picked up.
|
| - |
|
779 |
|
| 759 |
|
780 |
|
| 760 |
Parameters:
|
781 |
Parameters:
|
| 761 |
- warehouse_loc
|
- |
|
| 762 |
- item_id
|
782 |
- itemId
|
| 763 |
"""
|
783 |
"""
|
| 764 |
if warehouse_loc is None:
|
- |
|
| 765 |
raise InventoryServiceException(101, "Bad Warehouse Location")
|
- |
|
| 766 |
if not item_id:
|
- |
|
| 767 |
raise InventoryServiceException(101, "Bad Item id")
|
- |
|
| 768 |
|
784 |
|
| 769 |
item = Item.get_by(id=item_id)
|
785 |
item = Item.get_by(id=item_id)
|
| 770 |
logisticsLocation = warehouse_loc
|
- |
|
| 771 |
warehouse_ids = []
|
786 |
warehouse_ids = []
|
| 772 |
goodBillableWarehouses = []
|
787 |
goodBillableWarehouses = []
|
| 773 |
goodBillableWarehousesAtPreferredShippingLocation = []
|
788 |
goodBillableWarehousesAtPreferredShippingLocation = []
|
| 774 |
goodBillableWarehousesAtDefaultShippingLocation = []
|
789 |
goodBillableWarehousesAtDefaultShippingLocation = []
|
| 775 |
nonBillableWarehouses = []
|
790 |
nonBillableWarehouses = []
|
| Line 779... |
Line 794... |
| 779 |
continue
|
794 |
continue
|
| 780 |
if warehouse.shippingWarehouseId == item.defaultWarehouse and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD] and warehouse.billingWarehouseId:
|
795 |
if warehouse.shippingWarehouseId == item.defaultWarehouse and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD] and warehouse.billingWarehouseId:
|
| 781 |
goodBillableWarehousesAtDefaultShippingLocation.append(warehouse.id)
|
796 |
goodBillableWarehousesAtDefaultShippingLocation.append(warehouse.id)
|
| 782 |
if warehouse.billingWarehouseId is None:
|
797 |
if warehouse.billingWarehouseId is None:
|
| 783 |
nonBillableWarehouses.append(warehouse.id)
|
798 |
nonBillableWarehouses.append(warehouse.id)
|
| 784 |
if warehouse.logisticsLocation == logisticsLocation:
|
799 |
|
| 785 |
warehouse_ids.append(warehouse.id)
|
800 |
warehouse_ids.append(warehouse.id)
|
| 786 |
if warehouse.billingWarehouseId and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
|
801 |
if warehouse.billingWarehouseId and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
|
| 787 |
goodBillableWarehouses.append(warehouse.id)
|
802 |
goodBillableWarehouses.append(warehouse.id)
|
| 788 |
if item.preferredWarehouse and item.preferredWarehouse == warehouse.shippingWarehouseId:
|
803 |
if item.preferredWarehouse and item.preferredWarehouse == warehouse.shippingWarehouseId:
|
| 789 |
goodBillableWarehousesAtPreferredShippingLocation.append(warehouse.id)
|
804 |
goodBillableWarehousesAtPreferredShippingLocation.append(warehouse.id)
|
| 790 |
nonBillableWarehousesCorrespondingToPreferredShippingLocation.extend([w.id for w in Warehouse.query.filter_by(logisticsLocation=logisticsLocation, vendor_id = warehouse.vendor_id, billingWarehouseId = None).all()])
|
805 |
nonBillableWarehousesCorrespondingToPreferredShippingLocation.extend([w.id for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, billingWarehouseId = None).all()])
|
| 791 |
|
806 |
|
| 792 |
warehouse_retid = -1
|
807 |
warehouse_retid = -1
|
| 793 |
total_availability = 0
|
808 |
total_availability = 0
|
| 794 |
|
809 |
|
| 795 |
'''
|
810 |
'''
|
| Line 834... |
Line 849... |
| 834 |
for warehouse in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
|
849 |
for warehouse in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
|
| 835 |
if warehouse.billingWarehouseId:
|
850 |
if warehouse.billingWarehouseId:
|
| 836 |
billingWarehouseId = warehouse.billingWarehouseId
|
851 |
billingWarehouseId = warehouse.billingWarehouseId
|
| 837 |
break
|
852 |
break
|
| 838 |
|
853 |
|
| 839 |
logisticsLocation = warehouse.logisticsLocation
|
- |
|
| 840 |
|
- |
|
| 841 |
expectedDelay = item.expectedDelay
|
854 |
expectedDelay = item.expectedDelay
|
| 842 |
if expectedDelay is None:
|
855 |
if expectedDelay is None:
|
| 843 |
print 'expectedDelay field for this item was Null. Resetting it to 0'
|
856 |
print 'expectedDelay field for this item was Null. Resetting it to 0'
|
| 844 |
expectedDelay = 0
|
857 |
expectedDelay = 0
|
| 845 |
else:
|
858 |
else:
|
| Line 847... |
Line 860... |
| 847 |
|
860 |
|
| 848 |
if total_availability <= 0:
|
861 |
if total_availability <= 0:
|
| 849 |
expectedDelay = expectedDelay + __get_expected_procurement_delay(item)
|
862 |
expectedDelay = expectedDelay + __get_expected_procurement_delay(item)
|
| 850 |
expectedDelay = expectedDelay + __get_vendor_holiday_delay(item, expectedDelay)
|
863 |
expectedDelay = expectedDelay + __get_vendor_holiday_delay(item, expectedDelay)
|
| 851 |
|
864 |
|
| 852 |
return [logisticsLocation, int(warehouse_retid), total_availability, expectedDelay, billingWarehouseId]
|
865 |
item_availability_cache[item_id] = [int(warehouse_retid), expectedDelay, billingWarehouseId, item.sellingPrice]
|
| 853 |
|
866 |
|
| 854 |
def __get_warehouse_with_max_availability(warehouse_ids, item):
|
867 |
def __get_warehouse_with_max_availability(warehouse_ids, item):
|
| 855 |
warehouse_retid = -1
|
868 |
warehouse_retid = -1
|
| 856 |
max_availability = 0
|
869 |
max_availability = 0
|
| 857 |
total_availability = 0
|
870 |
total_availability = 0
|
| 858 |
|
871 |
|