| Line 71... |
Line 71... |
| 71 |
def is_active(item_id):
|
71 |
def is_active(item_id):
|
| 72 |
t_item_shipping_info = ItemShippingInfo()
|
72 |
t_item_shipping_info = ItemShippingInfo()
|
| 73 |
try:
|
73 |
try:
|
| 74 |
item = get_item(item_id)
|
74 |
item = get_item(item_id)
|
| 75 |
t_item_shipping_info.isRisky = item.risky
|
75 |
t_item_shipping_info.isRisky = item.risky
|
| 76 |
availability = __get_item_availability(item)
|
76 |
availability = __get_item_availability(item, None)
|
| 77 |
if item.risky and availability <= 0 and item.status == status.ACTIVE:
|
77 |
if item.risky and availability <= 0 and item.status == status.ACTIVE:
|
| 78 |
add_status_change_log(item, status.PAUSED_BY_RISK)
|
78 |
add_status_change_log(item, status.PAUSED_BY_RISK)
|
| 79 |
item.status = status.PAUSED_BY_RISK
|
79 |
item.status = status.PAUSED_BY_RISK
|
| 80 |
item.status_description = "This item is currently out of stock"
|
80 |
item.status_description = "This item is currently out of stock"
|
| 81 |
session.commit()
|
81 |
session.commit()
|
| Line 510... |
Line 510... |
| 510 |
"""
|
510 |
"""
|
| 511 |
|
511 |
|
| 512 |
def check_risky_item(item):
|
512 |
def check_risky_item(item):
|
| 513 |
if not item.risky:
|
513 |
if not item.risky:
|
| 514 |
return
|
514 |
return
|
| 515 |
availability = __get_item_availability(item)
|
515 |
availability = __get_item_availability(item, None)
|
| 516 |
if availability <= 0:
|
516 |
if availability <= 0:
|
| 517 |
if item.status == status.ACTIVE:
|
517 |
if item.status == status.ACTIVE:
|
| 518 |
change_item_status(item.id, status.PAUSED_BY_RISK)
|
518 |
change_item_status(item.id, status.PAUSED_BY_RISK)
|
| 519 |
try:
|
519 |
try:
|
| 520 |
mail("cnc.center@shop2020.in", "5h0p2o2o", ["chaitnaya.vats@shop2020.in", "abhishek.mathur@shop2020.in"], "Item is out of stock. ID: " + str(item.id) + " " + item.brand + " " + item.model_name + " " + item.model_number, " ", [])
|
520 |
mail("cnc.center@shop2020.in", "5h0p2o2o", ["chaitnaya.vats@shop2020.in", "abhishek.mathur@shop2020.in"], "Item is out of stock. ID: " + str(item.id) + " " + item.brand + " " + item.model_name + " " + item.model_number, " ", [])
|
| Line 523... |
Line 523... |
| 523 |
else:
|
523 |
else:
|
| 524 |
if item.status == status.PAUSED_BY_RISK:
|
524 |
if item.status == status.PAUSED_BY_RISK:
|
| 525 |
change_item_status(item.id, status.ACTIVE)
|
525 |
change_item_status(item.id, status.ACTIVE)
|
| 526 |
session.commit()
|
526 |
session.commit()
|
| 527 |
|
527 |
|
| - |
|
528 |
'''
|
| - |
|
529 |
This method returns quantity of a particular item across all warehouses whose ids is provided
|
| - |
|
530 |
if warehouse_ids is null it checks for inventory in all warehouses.
|
| - |
|
531 |
'''
|
| 528 |
def __get_item_availability(item):
|
532 |
def __get_item_availability(item, warehouse_ids):
|
| - |
|
533 |
if warehouse_ids is None:
|
| 529 |
all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
|
534 |
all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
|
| 530 |
availability = 0
|
535 |
availability = 0
|
| 531 |
reserved = 0
|
536 |
reserved = 0
|
| 532 |
for currInv in all_inventory:
|
537 |
for currInv in all_inventory:
|
| 533 |
availability = availability + currInv.availibility
|
538 |
availability = availability + currInv.availibility
|
| 534 |
reserved = reserved + currInv.reserved
|
539 |
reserved = reserved + currInv.reserved
|
| 535 |
return availability - reserved
|
540 |
return availability - reserved
|
| - |
|
541 |
else:
|
| - |
|
542 |
total_availability = 0
|
| - |
|
543 |
for warehouse_id in warehouse_ids:
|
| - |
|
544 |
try:
|
| - |
|
545 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
|
| - |
|
546 |
availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
| - |
|
547 |
except Exception as e:
|
| - |
|
548 |
print e
|
| - |
|
549 |
availability = 0
|
| - |
|
550 |
total_availability = total_availability + availability
|
| - |
|
551 |
return total_availability
|
| 536 |
|
552 |
|
| 537 |
def __get_item_reserved(item):
|
553 |
def __get_item_reserved(item):
|
| 538 |
all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
|
554 |
all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
|
| 539 |
reserved = 0
|
555 |
reserved = 0
|
| 540 |
for currInv in all_inventory:
|
556 |
for currInv in all_inventory:
|
| Line 610... |
Line 626... |
| 610 |
return True
|
626 |
return True
|
| 611 |
|
627 |
|
| 612 |
def get_item_availability_for_location(warehouse_loc, item_id):
|
628 |
def get_item_availability_for_location(warehouse_loc, item_id):
|
| 613 |
"""
|
629 |
"""
|
| 614 |
Determines the warehouse that should be used to fulfil an order for the given item.
|
630 |
Determines the warehouse that should be used to fulfil an order for the given item.
|
| 615 |
It first checks all the warehouses which are in the logistics location given by the
|
631 |
It first checks whether the preferred warehouse for that item is set or not. If set
|
| - |
|
632 |
and preference is sticky then that warehouse is used for fulfilment.
|
| - |
|
633 |
If preference is not sticky then we see if item is available in the preferred WH,
|
| 616 |
warehouse_loc parameter. If none of the warehouses there have any inventory, then the
|
634 |
in which case that warehouse is used otherwise we use that warehouse which has the max
|
| - |
|
635 |
availability. And if there is no inventory for that item in any warehouses then we use
|
| 617 |
preferred warehouse for the item is used.
|
636 |
default warehouse.
|
| - |
|
637 |
If preference is not set in that case we just find the warehouse with max availability
|
| - |
|
638 |
and in case of zero inventory we use default warehouse
|
| 618 |
|
639 |
|
| 619 |
Returns an ordered list of size 4 with following elements in the given order:
|
640 |
Returns an ordered list of size 4 with following elements in the given order:
|
| 620 |
1. Logistics location of the warehouse which was finally picked up to ship the order.
|
641 |
1. Logistics location of the warehouse which was finally picked up to ship the order.
|
| 621 |
2. Id of the warehouse which was finally picked up.
|
642 |
2. Id of the warehouse which was finally picked up.
|
| 622 |
3. Inventory size in the selected warehouse.
|
643 |
3. Inventory size in the selected warehouse.
|
| Line 630... |
Line 651... |
| 630 |
raise InventoryServiceException(101, "Bad Warehouse Location")
|
651 |
raise InventoryServiceException(101, "Bad Warehouse Location")
|
| 631 |
if not item_id:
|
652 |
if not item_id:
|
| 632 |
raise InventoryServiceException(101, "Bad Item id")
|
653 |
raise InventoryServiceException(101, "Bad Item id")
|
| 633 |
|
654 |
|
| 634 |
item = Item.get_by(id=item_id)
|
655 |
item = Item.get_by(id=item_id)
|
| 635 |
|
- |
|
| 636 |
#First try all warehouses in the suggested location.
|
656 |
logisticsLocation = warehouse_loc
|
| 637 |
warehouses = Warehouse.query.filter_by(logisticsLocation=warehouse_loc).all()
|
657 |
warehouses = Warehouse.query.filter_by(logisticsLocation=logisticsLocation).all()
|
| 638 |
warehouse_ids = [warehouse.id for warehouse in warehouses]
|
658 |
warehouse_ids = [warehouse.id for warehouse in warehouses]
|
| 639 |
warehouse_retid = -1
|
659 |
warehouse_retid = -1
|
| 640 |
max_availability = 0
|
660 |
|
| 641 |
total_availability = 0
|
661 |
total_availability = 0
|
| - |
|
662 |
'''
|
| - |
|
663 |
If warehouse preference is set and it is sticky then we should fulfil this order from this warehouse only.
|
| - |
|
664 |
But we still need to calculate total availability across warehouses.
|
| - |
|
665 |
'''
|
| - |
|
666 |
if (item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
|
| 642 |
for warehouse_id in warehouse_ids:
|
667 |
warehouse_retid = item.preferredWarehouse
|
| - |
|
668 |
warehouse = Warehouse.get_by(id=warehouse_retid)
|
| - |
|
669 |
logisticsLocation = warehouse.logisticsLocation
|
| - |
|
670 |
total_availability = __get_item_availability(item, warehouse_ids)
|
| - |
|
671 |
|
| - |
|
672 |
#If preference is not sticky then this order should be fulfilled from preferred WH if inventory available
|
| - |
|
673 |
#otherwise we should check for its availability elsewhere and fulfil this order from there, but if it is not available anywhere
|
| - |
|
674 |
#then we should fulfil this order from its default warehouse.
|
| - |
|
675 |
|
| - |
|
676 |
elif (not item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
|
| 643 |
try:
|
677 |
try:
|
| 644 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
|
678 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = item.preferredWarehouse, item_id = item_id).one()
|
| 645 |
availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
679 |
availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
| 646 |
except Exception as e:
|
680 |
except Exception as e:
|
| 647 |
print e
|
681 |
print e
|
| 648 |
availability = 0
|
682 |
availability = 0
|
| 649 |
if availability > max_availability:
|
683 |
if availability > 0:
|
| 650 |
warehouse_retid = warehouse_id
|
684 |
warehouse_retid = item.preferredWarehouse
|
| 651 |
max_availability = availability
|
685 |
total_availability = __get_item_availability(item, warehouse_ids)
|
| - |
|
686 |
else :
|
| - |
|
687 |
[logisticsLocation, warehouse_retid, total_availability] = \
|
| - |
|
688 |
__get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
|
| - |
|
689 |
warehouse_ids = warehouse_ids, item = item)
|
| - |
|
690 |
|
| - |
|
691 |
else :
|
| 652 |
total_availability = total_availability + availability
|
692 |
[logisticsLocation, warehouse_retid, total_availability] = \
|
| - |
|
693 |
__get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
|
| - |
|
694 |
warehouse_ids = warehouse_ids, item = item)
|
| 653 |
|
695 |
|
| - |
|
696 |
if item.expectedDelay is None:
|
| - |
|
697 |
print 'expectedDelay field for this item was Null. Resetting it to 0'
|
| - |
|
698 |
item.expectedDelay = 0
|
| - |
|
699 |
|
| - |
|
700 |
## FIXME Assign warehouse 5 (9D2) for all the hotspot products.
|
| - |
|
701 |
#if warehouse_retid in [warehouse.id for warehouse in get_warehouses_for_vendor(1)]:
|
| - |
|
702 |
if warehouse_retid in [1,2,3,4,5]:
|
| - |
|
703 |
warehouse_retid = 5
|
| - |
|
704 |
warehouse = Warehouse.get_by(id=warehouse_retid)
|
| - |
|
705 |
logisticsLocation = warehouse.logisticsLocation
|
| - |
|
706 |
|
| - |
|
707 |
return [logisticsLocation, int(warehouse_retid), total_availability, int(item.expectedDelay)]
|
| - |
|
708 |
|
| - |
|
709 |
def __get_warehouse_with_max_availability(warehouse_loc, warehouse_ids, item):
|
| - |
|
710 |
|
| - |
|
711 |
warehouse_retid = -1
|
| - |
|
712 |
max_availability = 0
|
| - |
|
713 |
total_availability = 0
|
| - |
|
714 |
|
| - |
|
715 |
for warehouse_id in warehouse_ids:
|
| - |
|
716 |
try:
|
| - |
|
717 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
|
| - |
|
718 |
availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
| - |
|
719 |
except Exception as e:
|
| - |
|
720 |
print e
|
| - |
|
721 |
availability = 0
|
| - |
|
722 |
if availability > max_availability:
|
| - |
|
723 |
warehouse_retid = warehouse_id
|
| - |
|
724 |
max_availability = availability
|
| - |
|
725 |
total_availability = total_availability + availability
|
| - |
|
726 |
|
| 654 |
#If no warehouse could be found, use the preferred warehouse for this item
|
727 |
#If no warehouse could be found, use the default warehouse for this item
|
| 655 |
if warehouse_retid == -1:
|
728 |
if warehouse_retid == -1:
|
| 656 |
# This is the case when all warehouses have exhausted their
|
729 |
# This is the case when all warehouses have exhausted their
|
| 657 |
# inventory of this item or no warehouse is available in this
|
730 |
# inventory of this item or no warehouse is available in this
|
| 658 |
# location.
|
731 |
# location.
|
| 659 |
warehouse_retid = int(item.preferredWarehouse)
|
732 |
warehouse_retid = int(item.defaultWarehouse)
|
| 660 |
warehouse = Warehouse.get_by(id=warehouse_retid)
|
733 |
warehouse = Warehouse.get_by(id=warehouse_retid)
|
| - |
|
734 |
warehouse_loc = warehouse.logisticsLocation
|
| 661 |
try:
|
735 |
try:
|
| 662 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item_id).one()
|
736 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item.id).one()
|
| 663 |
max_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
737 |
max_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
| 664 |
except Exception as e:
|
738 |
except Exception as e:
|
| 665 |
print e
|
739 |
print e
|
| 666 |
max_availability = 0
|
740 |
max_availability = 0
|
| 667 |
total_availability = max_availability
|
741 |
total_availability = max_availability
|
| 668 |
|
742 |
|
| 669 |
if item.expectedDelay is None:
|
743 |
return [warehouse_loc, warehouse_retid, total_availability]
|
| - |
|
744 |
'''
|
| 670 |
print 'expectedDelay field for this item was Null. Resetting it to 0'
|
745 |
def calculate_total_availability(warehouse_ids, item_id):
|
| 671 |
item.expectedDelay = 0
|
746 |
total_availability = 0
|
| - |
|
747 |
for warehouse_id in warehouse_ids:
|
| 672 |
|
748 |
try:
|
| 673 |
## FIXME Assign warehouse 5 (9D2) for all the hotspot products.
|
749 |
current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
|
| 674 |
#if warehouse_retid in [warehouse.id for warehouse in get_warehouses_for_vendor(1)]:
|
750 |
availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
|
| 675 |
if warehouse_retid in [1,2,3,4,5]:
|
751 |
except Exception as e:
|
| 676 |
warehouse_retid = 5
|
752 |
print e
|
| 677 |
warehouse = Warehouse.get_by(id=warehouse_retid)
|
753 |
availability = 0
|
| 678 |
|
- |
|
| 679 |
return [warehouse.logisticsLocation, warehouse_retid, total_availability, item.expectedDelay]
|
754 |
total_availability = total_availability + availability
|
| - |
|
755 |
return total_availability
|
| - |
|
756 |
'''
|
| 680 |
|
757 |
|
| 681 |
def get_warehouses_for_item(item_id):
|
758 |
def get_warehouses_for_item(item_id):
|
| 682 |
|
759 |
|
| 683 |
if not item_id:
|
760 |
if not item_id:
|
| 684 |
raise InventoryServiceException(101, "bad item_id")
|
761 |
raise InventoryServiceException(101, "bad item_id")
|
| Line 1089... |
Line 1166... |
| 1089 |
|
1166 |
|
| 1090 |
def send_product_notifications():
|
1167 |
def send_product_notifications():
|
| 1091 |
product_notifications = ProductNotification.query.all()
|
1168 |
product_notifications = ProductNotification.query.all()
|
| 1092 |
for product_notification in product_notifications:
|
1169 |
for product_notification in product_notifications:
|
| 1093 |
item = product_notification.item
|
1170 |
item = product_notification.item
|
| 1094 |
availability = __get_item_availability(item)
|
1171 |
availability = __get_item_availability(item, None)
|
| 1095 |
if availability > 0 and item.status == status.ACTIVE:
|
1172 |
if availability > 0 and item.status == status.ACTIVE:
|
| 1096 |
__enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
|
1173 |
__enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
|
| 1097 |
product_notification.delete()
|
1174 |
product_notification.delete()
|
| 1098 |
session.commit()
|
1175 |
session.commit()
|
| 1099 |
return True
|
1176 |
return True
|