Subversion Repositories SmartDukaan

Rev

Rev 5080 | Rev 5114 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5080 Rev 5110
Line 14... Line 14...
14
    to_t_vendor_item_pricing, to_t_source
14
    to_t_vendor_item_pricing, to_t_source
15
from shop2020.model.v1.catalog.impl.DataService import Item, Warehouse, \
15
from shop2020.model.v1.catalog.impl.DataService import Item, Warehouse, \
16
    ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo, ItemChangeLog, \
16
    ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo, ItemChangeLog, \
17
    Category, EntityIDGenerator, VendorItemPricing, VendorItemMapping, Vendor, \
17
    Category, EntityIDGenerator, VendorItemPricing, VendorItemMapping, Vendor, \
18
    SimilarItems, ProductNotification, Source, SourceItemPricing, AuthorizationLog, \
18
    SimilarItems, ProductNotification, Source, SourceItemPricing, AuthorizationLog, \
19
    MissedInventoryUpdate, VendorItemProcurementDelay, VendorHolidays
19
    MissedInventoryUpdate, BadInventorySnapshot, VendorItemProcurementDelay, \
-
 
20
    VendorHolidays
20
from shop2020.thriftpy.model.v1.catalog.ttypes import InventoryServiceException, \
21
from shop2020.thriftpy.model.v1.catalog.ttypes import InventoryServiceException, \
21
    status, ItemShippingInfo, HolidayType
22
    status, ItemShippingInfo, HolidayType, InventoryType, WarehouseType
22
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
23
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
23
from shop2020.utils import EmailAttachmentSender
24
from shop2020.utils import EmailAttachmentSender
24
from shop2020.utils.EmailAttachmentSender import mail
25
from shop2020.utils.EmailAttachmentSender import mail
25
from shop2020.utils.Utils import log_entry, to_py_date, log_risky_flag
26
from shop2020.utils.Utils import log_entry, to_py_date, log_risky_flag
26
from sqlalchemy import desc, asc
27
from sqlalchemy import desc, asc
27
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
28
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
28
from sqlalchemy.sql.expression import and_, or_, distinct, func
29
from sqlalchemy.sql.expression import and_, or_, distinct, func
29
from string import Template
30
from string import Template
30
from urllib2 import HTTPBasicAuthHandler
31
from urllib2 import HTTPBasicAuthHandler
-
 
32
import calendar
31
import datetime
33
import datetime
32
import sys
34
import sys
33
import urllib2
35
import urllib2
34
import calendar
-
 
35
from functools import partial
36
from functools import partial
36
 
37
 
37
import threading
38
import threading
38
 
39
 
39
to_addresses = ["cnc.center@shop2020.in", "ashutosh.saxena@shop2020.in"]
40
to_addresses = ["cnc.center@shop2020.in", "ashutosh.saxena@shop2020.in"]
Line 365... Line 366...
365
 
366
 
366
def update_inventory_history(warehouse_id, timestamp, availability):
367
def update_inventory_history(warehouse_id, timestamp, availability):
367
    warehouse = get_Warehouse(warehouse_id)
368
    warehouse = get_Warehouse(warehouse_id)
368
    if not warehouse:
369
    if not warehouse:
369
        raise InventoryServiceException(107, "Warehouse? Where?")
370
        raise InventoryServiceException(107, "Warehouse? Where?")
370
    vendors = get_vendors_for_warehouse(warehouse_id)
-
 
371
    if len(vendors) > 1:
-
 
372
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
-
 
373
    vendor = vendors[0]
371
    vendor = warehouse.vendor_id
374
    time = datetime.datetime.now()
372
    time = datetime.datetime.now()
375
    for item_key, quantity in availability.iteritems():
373
    for item_key, quantity in availability.iteritems():
376
        try:
374
        try:
377
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
375
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
378
            item = vendor_item_mapping.item
376
            item = vendor_item_mapping.item
Line 394... Line 392...
394
        raise InventoryServiceException(107, "Warehouse? Where?")
392
        raise InventoryServiceException(107, "Warehouse? Where?")
395
     
393
     
396
    time = datetime.datetime.now()
394
    time = datetime.datetime.now()
397
    warehouse.lastCheckedOn = time
395
    warehouse.lastCheckedOn = time
398
    warehouse.vendorString = timestamp
396
    warehouse.vendorString = timestamp
399
    vendors = get_vendors_for_warehouse(warehouse_id)
-
 
400
    if len(vendors) > 1:
-
 
401
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
-
 
402
    vendor = vendors[0]
397
    vendor = warehouse.vendor_id
403
    session.commit()
398
    session.commit()
404
    for item_key, quantity in availability.iteritems():
399
    for item_key, quantity in availability.iteritems():
405
        try:
400
        try:
406
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
401
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
407
            item = vendor_item_mapping.item
402
            item = vendor_item_mapping.item
Line 458... Line 453...
458
 
453
 
459
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
454
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
460
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
455
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
461
    # One email per product key mismatch
456
    # One email per product key mismatch
462
    if not missedInventoryUpdate:
457
    if not missedInventoryUpdate:
463
        EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', ['mandeep.dhir@shop2020.in', 'chaitnaya.vats@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
458
        EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', ['mandeep.dhir@shop2020.in', 'chaitnaya.vats@shop2020.in', 'asghar.bilgrami@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
464
        missedInventoryUpdate = MissedInventoryUpdate()
459
        missedInventoryUpdate = MissedInventoryUpdate()
465
        missedInventoryUpdate.itemKey = item_key
460
        missedInventoryUpdate.itemKey = item_key
466
        missedInventoryUpdate.quantity = quantity
461
        missedInventoryUpdate.quantity = quantity
467
        missedInventoryUpdate.isIgnored = 1
462
        missedInventoryUpdate.isIgnored = 1
468
        missedInventoryUpdate.timestamp = datetime.datetime.now()
463
        missedInventoryUpdate.timestamp = datetime.datetime.now()
Line 484... Line 479...
484
    current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
479
    current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
485
    session.commit()
480
    session.commit()
486
    if current_inventory_snapshot.availibility < 0:
481
    if current_inventory_snapshot.availibility < 0:
487
        __send_alert_for_negative_availability(get_item(itemId), current_inventory_snapshot.availibility, get_Warehouse(warehouseId))
482
        __send_alert_for_negative_availability(get_item(itemId), current_inventory_snapshot.availibility, get_Warehouse(warehouseId))
488
    check_risky_item(get_item(itemId)) 
483
    check_risky_item(get_item(itemId)) 
489
    
-
 
490
'''
484
 
491
def get_item_inventoy(item_id):
485
def add_bad_inventory(itemId, warehouseId, quantity):
492
    
-
 
493
    inventory = Item.get_by(id=item_id).currentInventory
486
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
494
    if not inventory:
487
    if not bad_inventory_snapshot:
-
 
488
        bad_inventory_snapshot = BadInventorySnapshot()
-
 
489
        bad_inventory_snapshot.item_id = itemId
-
 
490
        bad_inventory_snapshot.warehouse_id = warehouseId
-
 
491
        bad_inventory_snapshot.availability = 0
495
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
492
    # added the difference in the current inventory    
-
 
493
    bad_inventory_snapshot.availability += quantity
496
    return inventory
494
    session.commit()
497
'''
-
 
-
 
495
    if bad_inventory_snapshot.availability < 0:
-
 
496
        __send_alert_for_negative_availability(get_item(itemId), bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
498
 
497
 
499
def get_item_inventory_by_item_id(item_id):
498
def get_item_inventory_by_item_id(item_id):
500
    inventory = Item.get_by(id=item_id).currentInventory
499
    inventory = Item.get_by(id=item_id).currentInventory
501
    if not inventory:
500
    if not inventory:
502
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
501
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
Line 732... Line 731...
732
    return True
731
    return True
733
 
732
 
734
def get_item_availability_for_location(warehouse_loc, item_id):
733
def get_item_availability_for_location(warehouse_loc, item_id):
735
    """
734
    """
736
    Determines the warehouse that should be used to fulfil an order for the given item.
735
    Determines the warehouse that should be used to fulfil an order for the given item.
-
 
736
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
-
 
737
 
737
    It first checks whether the preferred warehouse for that item is set or not. If set 
738
    If item's Preferred warehouse is present
-
 
739
        If item marked sticky
738
    and preference is sticky then that warehouse is used for fulfilment.
740
            use GOOD type warehouse at preferred warehouse with maximum availability. 
739
    If preference is not sticky then we see if item is available in the preferred WH,
741
            If not available at any, then use THIRD_PARTY warehouse without billing support 
740
    in which case that warehouse is used otherwise we use that warehouse which has the max
742
            corresponding to preferred warehouse where available. 
741
    availability. And if there is no inventory for that item in any warehouses then we use
743
            If still not available, then use any GOOD type warehouse with billing support.
742
    default warehouse.
744
        else
-
 
745
            if availability > 0 at least one of GOOD type warehouses in preferred warehouse
743
    If preference is not set in that case we just find the warehouse with max availability
746
                use GOOD type warehouse at preferred warehouse with maximum availability
-
 
747
 
-
 
748
    If available at no warehouse
744
    and in case of zero inventory we use default warehouse
749
        use any GOOD type warehouse at default warehouse
745
    
750
    else
-
 
751
        if available at any warehouse of type GOOD with billing support
-
 
752
            use warehouse of type GOOD with billing support with maximum availability
-
 
753
        else
-
 
754
            if preferred warehouse is present and availability at preferred warehouse's corresponding ThirdPartyWarehouse without billing support > 0
-
 
755
                preferred warehouse's corresponding ThirdPartyWarehouse without billing support with maximum availability
-
 
756
            else
-
 
757
                use ThirdPartyWarehouse without billing support with maximum availability
-
 
758
                
746
    Returns an ordered list of size 4 with following elements in the given order:
759
    Returns an ordered list of size 4 with following elements in the given order:
747
    1. Logistics location of the warehouse which was finally picked up to ship the order.
760
    1. Logistics location of the warehouse which was finally picked up to ship the order.
748
    2. Id of the warehouse which was finally picked up.
761
    2. Id of the warehouse which was finally picked up.
749
    3. Inventory size in the selected warehouse.
762
    3. Inventory size in the selected warehouse.
750
    4. Expected delay added by the category manager.
763
    4. Expected delay added by the category manager.
751
    
764
 
752
    Parameters:
765
    Parameters:
753
     - warehouse_loc
766
     - warehouse_loc
754
     - item_id
767
     - item_id
755
    """
768
    """
756
    if warehouse_loc is None:
769
    if warehouse_loc is None:
Line 758... Line 771...
758
    if not item_id:
771
    if not item_id:
759
        raise InventoryServiceException(101, "Bad Item id")
772
        raise InventoryServiceException(101, "Bad Item id")
760
    
773
    
761
    item = Item.get_by(id=item_id)
774
    item = Item.get_by(id=item_id)
762
    logisticsLocation = warehouse_loc
775
    logisticsLocation = warehouse_loc
-
 
776
    warehouse_ids = []
-
 
777
    goodBillableWarehouses = []
-
 
778
    goodBillableWarehousesAtPreferredShippingLocation = []
-
 
779
    goodBillableWarehousesAtDefaultShippingLocation = []
-
 
780
    nonBillableWarehouses = []
-
 
781
    nonBillableWarehousesCorrespondingToPreferredShippingLocation = []
-
 
782
    for warehouse in Warehouse.query.all():
-
 
783
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD]):
-
 
784
            continue
-
 
785
        if warehouse.shippingWarehouseId == item.defaultWarehouse and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD] and warehouse.billingWarehouseId:
-
 
786
            goodBillableWarehousesAtDefaultShippingLocation.append(warehouse.id)
-
 
787
        if warehouse.billingWarehouseId is None:
-
 
788
            nonBillableWarehouses.append(warehouse.id)
763
    warehouses = Warehouse.query.filter_by(logisticsLocation=logisticsLocation).all()
789
        if warehouse.logisticsLocation == logisticsLocation:
764
    warehouse_ids = [warehouse.id for warehouse in warehouses]
790
            warehouse_ids.append(warehouse.id)
-
 
791
            if warehouse.billingWarehouseId and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
-
 
792
                goodBillableWarehouses.append(warehouse.id)
-
 
793
                if item.preferredWarehouse and item.preferredWarehouse == warehouse.shippingWarehouseId:
-
 
794
                    goodBillableWarehousesAtPreferredShippingLocation.append(warehouse.id)
-
 
795
                    nonBillableWarehousesCorrespondingToPreferredShippingLocation.extend([w.id for w in Warehouse.query.filter_by(logisticsLocation=logisticsLocation, vendor_id = warehouse.vendor_id, billingWarehouseId = None).all()])
-
 
796
 
765
    warehouse_retid = -1
797
    warehouse_retid = -1
766
    
-
 
767
    total_availability = 0
798
    total_availability = 0
-
 
799
 
768
    '''
800
    '''
769
    If warehouse preference is set and it is sticky then we should fulfil this order from this warehouse only.
801
    If warehouse preference is set and it is sticky then we should fulfil this order from this warehouse only.
770
    But we still need to calculate total availability across warehouses.
802
    But we still need to calculate total availability across warehouses.
771
    '''
803
    '''
772
    if (item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
804
    if (item.isWarehousePreferenceSticky and item.preferredWarehouse):
-
 
805
        [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(goodBillableWarehousesAtPreferredShippingLocation, item)
773
        warehouse_retid = item.preferredWarehouse
806
        if warehouse_retid == -1:
774
        warehouse = Warehouse.get_by(id=warehouse_retid)
807
            [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(nonBillableWarehousesCorrespondingToPreferredShippingLocation, item)
775
        logisticsLocation = warehouse.logisticsLocation
808
            if warehouse_retid == -1:
776
        total_availability = __get_item_availability(item, [warehouse_retid])
809
                warehouse_retid = goodBillableWarehousesAtPreferredShippingLocation[0]
777
    
-
 
778
    #If preference is not sticky then this order should be fulfilled from preferred WH if inventory available
810
    elif (not item.isWarehousePreferenceSticky and item.preferredWarehouse):
779
    #otherwise we should check for its availability elsewhere and fulfil this order from there, but if it is not available anywhere
811
        [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(goodBillableWarehousesAtPreferredShippingLocation, item)
780
    #then we should fulfil this order from its default warehouse.
-
 
781
    
812
 
782
    elif (not item.isWarehousePreferenceSticky and item.preferredWarehouse is not None):
-
 
783
        try:
813
    if warehouse_retid == -1:
784
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = item.preferredWarehouse, item_id = item_id).one()
-
 
785
            availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
814
        [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(warehouse_ids, item)
786
        except Exception as e:
815
        if warehouse_retid == -1:
-
 
816
            warehouse_retid = goodBillableWarehousesAtDefaultShippingLocation[0]
787
            print e
817
        else:
788
            availability = 0    
818
            [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(goodBillableWarehouses, item)
789
        if availability > 0:
819
            if warehouse_retid == -1:
790
            warehouse_retid = item.preferredWarehouse
820
                if item.preferredWarehouse:
791
            total_availability = availability
821
                    [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(nonBillableWarehousesCorrespondingToPreferredShippingLocation, item)
792
        else :
-
 
793
            [logisticsLocation, warehouse_retid, total_availability] = \
822
                    if warehouse_retid == -1:
794
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
823
                        # Availability at Good Billable warehouses is Zero, so can safely use all warehouse_ids to capture the thirdparty virtual/good one
795
                                                            warehouse_ids = warehouse_ids, item = item)
824
                        [warehouse_retid, total_availability] = __get_warehouse_with_max_availability(warehouse_ids, item)
796
           
-
 
797
    else :
825
 
798
        [logisticsLocation, warehouse_retid, total_availability] = \
826
    warehouse = Warehouse.get_by(id=warehouse_retid)
799
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
827
    billingWarehouseId = warehouse.billingWarehouseId
800
                                                            warehouse_ids = warehouse_ids, item = item)
-
 
801
    
828
    
802
    ## FIXME Assign warehouse 5 (9D2) for all the hotspot products.
829
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
803
    #if warehouse_retid in [warehouse.id for warehouse in get_warehouses_for_vendor(1)]:
830
    if warehouse.billingWarehouseId is None:
804
    if int(warehouse_retid) in [1,2,3,4,5]:
831
        for warehouse in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
805
        warehouse_retid = 5
832
            if warehouse.billingWarehouseId:
806
        warehouse = Warehouse.get_by(id=warehouse_retid)
833
                billingWarehouseId = warehouse.billingWarehouseId
-
 
834
                break
-
 
835
 
807
        logisticsLocation = warehouse.logisticsLocation  
836
    logisticsLocation = warehouse.logisticsLocation  
808
 
837
 
809
    expectedDelay = item.expectedDelay 
838
    expectedDelay = item.expectedDelay 
810
    if expectedDelay is None:
839
    if expectedDelay is None:
811
        print 'expectedDelay field for this item was Null. Resetting it to 0'
840
        print 'expectedDelay field for this item was Null. Resetting it to 0'
812
        expectedDelay = 0
841
        expectedDelay = 0
Line 815... Line 844...
815
    
844
    
816
    if total_availability <= 0:
845
    if total_availability <= 0:
817
        expectedDelay = expectedDelay + __get_expected_procurement_delay(item)
846
        expectedDelay = expectedDelay + __get_expected_procurement_delay(item)
818
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(item, expectedDelay)
847
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(item, expectedDelay)
819
        
848
        
820
    return [logisticsLocation, int(warehouse_retid), total_availability, expectedDelay]
849
    return [logisticsLocation, int(warehouse_retid), total_availability, expectedDelay, billingWarehouseId]
821
 
850
 
822
def __get_warehouse_with_max_availability(warehouse_loc, warehouse_ids, item):
851
def __get_warehouse_with_max_availability(warehouse_ids, item):
823
    
-
 
824
    warehouse_retid = -1
852
    warehouse_retid = -1
825
    max_availability = 0
853
    max_availability = 0
826
    total_availability = 0
854
    total_availability = 0
827
 
855
 
828
    for warehouse_id in warehouse_ids:
-
 
829
            try:
856
    if item.currentInventory:
830
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
-
 
831
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
-
 
832
            except Exception as e:
857
        for entry in item.currentInventory:
833
                print e
858
            if entry.warehouse_id in warehouse_ids:
834
                availability = 0    
859
                availability = entry.availibility - entry.reserved
835
            if availability > max_availability:
860
                if availability > max_availability:
836
                warehouse_retid = warehouse_id
861
                    warehouse_retid = entry.warehouse_id
837
                max_availability = availability
862
                    max_availability = availability
838
            total_availability = total_availability + availability
-
 
839
        
-
 
840
    #If no warehouse could be found, use the default warehouse for this item
-
 
841
    if warehouse_retid == -1:
-
 
842
        # This is the case when all warehouses have exhausted their
-
 
843
        # inventory of this item or no warehouse is available in this
-
 
844
        # location.
-
 
845
        warehouse_retid = int(item.defaultWarehouse)
-
 
846
        warehouse = Warehouse.get_by(id=warehouse_retid)
-
 
847
        warehouse_loc = warehouse.logisticsLocation
-
 
848
        try:
-
 
849
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item.id).one()
-
 
850
            max_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
-
 
851
        except Exception as e:
-
 
852
            print e
-
 
853
            max_availability = 0
-
 
854
        total_availability = max_availability
863
                total_availability += availability
855
 
864
 
856
    return [warehouse_loc, warehouse_retid, total_availability]
865
    return [warehouse_retid, total_availability]
857
'''    
-
 
858
def calculate_total_availability(warehouse_ids, item_id):
-
 
859
    total_availability = 0
-
 
860
    for warehouse_id in warehouse_ids:
-
 
861
            try:
-
 
862
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
-
 
863
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
-
 
864
            except Exception as e:
-
 
865
                print e
-
 
866
                availability = 0    
-
 
867
            total_availability = total_availability + availability
-
 
868
    return total_availability
-
 
869
'''
-
 
870
 
866
 
871
def __get_expected_procurement_delay(item):
867
def __get_expected_procurement_delay(item):
872
    procurementDelay = 2
868
    procurementDelay = 2
873
    try:
869
    try:
874
        if item.preferredVendor:
870
        if item.preferredVendor:
Line 1456... Line 1452...
1456
 
1452
 
1457
def send_product_notifications():
1453
def send_product_notifications():
1458
    product_notifications = ProductNotification.query.all()
1454
    product_notifications = ProductNotification.query.all()
1459
    for product_notification in product_notifications:
1455
    for product_notification in product_notifications:
1460
        item = product_notification.item
1456
        item = product_notification.item
1461
        availability = __get_item_availability(item, None)
-
 
1462
        if availability > 0 and item.status == status.ACTIVE:
1457
        if item.status == status.ACTIVE:
1463
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1458
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1464
            product_notification.delete()
1459
            product_notification.delete()
1465
    session.commit()
1460
    session.commit()
1466
    return True
1461
    return True
1467
   
1462
   
Line 1665... Line 1660...
1665
def get_pending_orders_inventory(vendor_id=1):
1660
def get_pending_orders_inventory(vendor_id=1):
1666
    """
1661
    """
1667
    Returns a list of inventory stock for items for which there are pending orders.
1662
    Returns a list of inventory stock for items for which there are pending orders.
1668
    """
1663
    """
1669
    
1664
    
1670
    warehouse_ids = [warehouse.id for warehouse in get_warehouses_for_vendor(vendor_id)]
1665
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
1671
    pending_items_inventory = []
1666
    pending_items_inventory = []
1672
    if warehouse_ids:
1667
    if warehouse_ids:
1673
        pending_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availibility), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
1668
        pending_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availibility), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
1674
    return pending_items_inventory
1669
    return pending_items_inventory
1675
 
1670
 
Line 1724... Line 1719...
1724
    return ds_vendor.id
1719
    return ds_vendor.id
1725
 
1720
 
1726
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1721
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1727
    return True
1722
    return True
1728
 
1723
 
1729
def get_vendors_for_warehouse(warehouse_id):
-
 
1730
    try:
-
 
1731
        warehouse = Warehouse.get_by(id=warehouse_id)
-
 
1732
        return warehouse.vendors
-
 
1733
    except:
-
 
1734
        raise InventoryServiceException(108, "Bad Warehouse Id")
-
 
1735
 
-
 
1736
def get_warehouses_for_vendor(vendorId):
-
 
1737
    try:
-
 
1738
        vendor = get_Vendor(vendorId)
-
 
1739
        return vendor.warehouses
-
 
1740
    except:
-
 
1741
        raise InventoryServiceException(108, "Bad Vendor Id")
-
 
1742
 
-
 
1743
def add_authorization_log_for_item(itemId, username, reason):
1724
def add_authorization_log_for_item(itemId, username, reason):
1744
    if not itemId or not username:
1725
    if not itemId or not username:
1745
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1726
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1746
    authorize_log = AuthorizationLog()
1727
    authorize_log = AuthorizationLog()
1747
    authorize_log.item_id = itemId
1728
    authorize_log.item_id = itemId