Subversion Repositories SmartDukaan

Rev

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

Rev 5966 Rev 5978
Line 144... Line 144...
144
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
144
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
145
    session.commit()
145
    session.commit()
146
 
146
 
147
    #**Update item availability cache**#
147
    #**Update item availability cache**#
148
    for item_id in item_ids:
148
    for item_id in item_ids:
149
        __update_item_availability_cache(item_id)
149
        clear_item_availability_cache(item_id)
150
        __check_risky_item(item_id)
-
 
151
 
150
 
152
def __send_alert_for_negative_reserved(item, reserved, warehouse):
151
def __send_alert_for_negative_reserved(item, reserved, warehouse):
153
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
152
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
154
    EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'amar.kumar@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
153
    EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'amar.kumar@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
155
 
154
 
Line 183... Line 182...
183
        current_inventory_snapshot.reserved = 0
182
        current_inventory_snapshot.reserved = 0
184
    # added the difference in the current inventory    
183
    # added the difference in the current inventory    
185
    current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
184
    current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
186
    session.commit()
185
    session.commit()
187
    #**Update item availability cache**#
186
    #**Update item availability cache**#
188
    __update_item_availability_cache(itemId)
187
    clear_item_availability_cache(itemId)
189
    if current_inventory_snapshot.availability < 0:
188
    if current_inventory_snapshot.availability < 0:
190
        item = __get_item_from_master(itemId)
189
        item = __get_item_from_master(itemId)
191
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId))
190
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
192
    __check_risky_item(itemId) 
-
 
193
 
191
 
194
def add_bad_inventory(itemId, warehouseId, quantity):
192
def add_bad_inventory(itemId, warehouseId, quantity):
195
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
193
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
196
    if not bad_inventory_snapshot:
194
    if not bad_inventory_snapshot:
197
        bad_inventory_snapshot = BadInventorySnapshot()
195
        bad_inventory_snapshot = BadInventorySnapshot()
Line 301... Line 299...
301
    reservation.promised_shipping_timestamp = promised_shipping_timestamp
299
    reservation.promised_shipping_timestamp = promised_shipping_timestamp
302
    reservation.reserved = quantity
300
    reservation.reserved = quantity
303
    
301
    
304
    session.commit()
302
    session.commit()
305
    #**Update item availability cache**#
303
    #**Update item availability cache**#
306
    __update_item_availability_cache(item_id)
304
    clear_item_availability_cache(item_id)
307
    __check_risky_item(item_id)
-
 
308
    return True
305
    return True
309
 
306
 
310
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
307
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
311
    if not warehouse_id:
308
    if not warehouse_id:
312
        raise InventoryServiceException(101, "bad warehouse_id")
309
        raise InventoryServiceException(101, "bad warehouse_id")
Line 321... Line 318...
321
            reservation.delete()
318
            reservation.delete()
322
        else:
319
        else:
323
            reservation.reserved -= quantity
320
            reservation.reserved -= quantity
324
        session.commit()
321
        session.commit()
325
        #**Update item availability cache**#
322
        #**Update item availability cache**#
326
        __update_item_availability_cache(item_id)
323
        clear_item_availability_cache(item_id)
327
        __check_risky_item(item_id)
-
 
328
        if current_inventory_snapshot.reserved < 0:
324
        if current_inventory_snapshot.reserved < 0:
329
            item = __get_item_from_master(item_id)
325
            item = __get_item_from_master(item_id)
330
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
326
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
331
        return True
327
        return True
332
    except:
328
    except:
333
        print "Unexpected error:", sys.exc_info()[0]
329
        print "Unexpected error:", sys.exc_info()[0]
334
        return False
330
        return False
335
 
331
 
336
def get_item_availability_for_location(item_id):
332
def get_item_availability_for_location(item_id, source_id):
337
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id)
333
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
338
    if item_availability:
334
    if item_availability:
339
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability]
335
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability]
340
    else:
336
    else:
341
        __update_item_availability_cache(item_id)
337
        __update_item_availability_cache(item_id, source_id)
-
 
338
            ##Check risky status for the source
-
 
339
        __check_risky_item(item_id, source_id)
342
        return get_item_availability_for_location(item_id)
340
        return get_item_availability_for_location(item_id, source_id)
343
    
341
    
344
def clear_item_availability_cache():
342
def clear_item_availability_cache(item_id = None):
-
 
343
    if item_id:
-
 
344
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
-
 
345
    else:
345
    ItemAvailabilityCache.query.delete()
346
        ItemAvailabilityCache.query.delete()
346
    session.commit()
347
    session.commit()
347
 
348
 
348
def __update_item_availability_cache(item_id):
349
def __update_item_availability_cache(item_id, source_id):
349
    """
350
    """
350
    Determines the warehouse that should be used to fulfil an order for the given item.
351
    Determines the warehouse that should be used to fulfil an order for the given item.
351
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
352
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
352
 
353
 
353
    It will be ensured that every item has either a preferred vendor specified or at least for one vendor its transfer price should be defined.
354
    It will be ensured that every item has either a preferred vendor specified or at least for one vendor its transfer price should be defined.
Line 377... Line 378...
377
    3. Id of the warehouse which was finally picked up.
378
    3. Id of the warehouse which was finally picked up.
378
 
379
 
379
    Parameters:
380
    Parameters:
380
     - itemId
381
     - itemId
381
    """
382
    """
382
    item = __get_item_from_master(item_id)
383
    item = __get_item_from_source(item_id, source_id)
383
    item_pricing = {}
384
    item_pricing = {}
384
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
385
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
385
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
386
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
386
 
387
 
387
    warehouses = {}
388
    warehouses = {}
Line 433... Line 434...
433
        expectedDelay = 0
434
        expectedDelay = 0
434
    else:
435
    else:
435
        expectedDelay = int(item.expectedDelay)
436
        expectedDelay = int(item.expectedDelay)
436
 
437
 
437
    if total_availability <= 0:
438
    if total_availability <= 0:
438
        expectedDelay = expectedDelay + __get_expected_procurement_delay(item)
439
        expectedDelay = expectedDelay + __get_expected_procurement_delay(item.id, item.preferredVendor)
439
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(item, expectedDelay)
440
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(item.preferredVendor, expectedDelay)
440
    else:
441
    else:
441
        if warehouse.transferDelayInHours:
442
        if warehouse.transferDelayInHours:
442
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
443
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
443
 
444
 
444
    total_availability = 0
445
    total_availability = 0
445
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
446
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
446
        total_availability += entry.availability - entry.reserved
447
        total_availability += entry.availability - entry.reserved
447
 
448
 
448
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id)
449
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
449
    if item_availability_cache is None:
450
    if item_availability_cache is None:
450
        item_availability_cache = ItemAvailabilityCache()
451
        item_availability_cache = ItemAvailabilityCache()
451
        item_availability_cache.itemId = item_id
452
        item_availability_cache.itemId = item_id
-
 
453
        item_availability_cache.sourceId = source_id
452
    item_availability_cache.warehouseId = int(warehouse_retid)
454
    item_availability_cache.warehouseId = int(warehouse_retid)
453
    item_availability_cache.expectedDelay = expectedDelay
455
    item_availability_cache.expectedDelay = expectedDelay
454
    item_availability_cache.billingWarehouseId = billingWarehouseId
456
    item_availability_cache.billingWarehouseId = billingWarehouseId
455
    item_availability_cache.sellingPrice = item.sellingPrice
457
    item_availability_cache.sellingPrice = item.sellingPrice
456
    item_availability_cache.totalAvailability = total_availability
458
    item_availability_cache.totalAvailability = total_availability
Line 517... Line 519...
517
                max_availability = availability
519
                max_availability = availability
518
            total_availability += availability
520
            total_availability += availability
519
 
521
 
520
    return [warehouse_retid, total_availability]
522
    return [warehouse_retid, total_availability]
521
 
523
 
522
def __get_expected_procurement_delay(item):
524
def __get_expected_procurement_delay(item_id, preferredVendor):
523
    procurementDelay = 2
525
    procurementDelay = 2
524
    try:
526
    try:
525
        if item.preferredVendor:
527
        if preferredVendor:
526
            delays = VendorItemProcurementDelay.query.filter_by(vendor_id = item.preferredVendor, item_id = item.id).all()
528
            delays = VendorItemProcurementDelay.query.filter_by(vendor_id = preferredVendor, item_id = item_id).all()
527
        else:
529
        else:
528
            delays = VendorItemProcurementDelay.query.filter_by(item_id = item.id).all()
530
            delays = VendorItemProcurementDelay.query.filter_by(item_id = item_id).all()
529
        
531
        
530
        procurementDelay= min([delay.procurementDelay for delay in delays])
532
        procurementDelay= min([delay.procurementDelay for delay in delays])
531
    except Exception as e:
533
    except Exception as e:
532
        print e
534
        print e
533
    return procurementDelay
535
    return procurementDelay
534
    
536
    
535
def __get_vendor_holiday_delay(item, expectedDelay):
537
def __get_vendor_holiday_delay(preferredVendor, expectedDelay):
536
    holidayDelay = 0
538
    holidayDelay = 0
537
    try:
539
    try:
538
        if item.preferredVendor:
540
        if preferredVendor:
539
            holidays = VendorHolidays.query.filter_by(vendor_id = item.preferredVendor).all()
541
            holidays = VendorHolidays.query.filter_by(vendor_id = preferredVendor).all()
540
            currentDate = datetime.date.today()
542
            currentDate = datetime.date.today()
541
            expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
543
            expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
542
            for holiday in holidays:
544
            for holiday in holidays:
543
                if holiday.holidayType == HolidayType.WEEKLY and holiday.holidayValue != calendar.SUNDAY:
545
                if holiday.holidayType == HolidayType.WEEKLY and holiday.holidayValue != calendar.SUNDAY:
544
                    if currentDate.weekday() > holiday.holidayValue:
546
                    if currentDate.weekday() > holiday.holidayValue:
Line 755... Line 757...
755
            quantity = 0
757
            quantity = 0
756
 
758
 
757
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
759
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
758
        if currentInventorySnapshot:
760
        if currentInventorySnapshot:
759
            currentInventorySnapshot.availability = quantity
761
            currentInventorySnapshot.availability = quantity
760
            __update_item_availability_cache(itemId) 
762
            clear_item_availability_cache(itemId) 
761
            __check_risky_item(currentInventorySnapshot.item_id)
-
 
762
        else:
763
        else:
763
            add_inventory(itemId, warehouseId, quantity)
764
            add_inventory(itemId, warehouseId, quantity)
764
 
765
 
765
    else:
766
    else:
766
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
767
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
767
    session.commit()
768
    session.commit()
768
 
769
 
769
def reset_availability_for_warehouse(warehouseId):
770
def reset_availability_for_warehouse(warehouseId):
770
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
771
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
771
        currentInventorySnapshot.availability = 0
772
        currentInventorySnapshot.availability = 0
772
        __update_item_availability_cache(currentInventorySnapshot.item_id)
773
        clear_item_availability_cache(currentInventorySnapshot.item_id) 
773
        __check_risky_item(currentInventorySnapshot.item_id) 
-
 
774
    session.commit()
774
    session.commit()
775
 
775
 
776
    
776
    
777
def __send_mail(subject, message):
777
def __send_mail(subject, message):
778
    try:
778
    try:
Line 812... Line 812...
812
def update_vendor_string(warehouseId, vendorString):
812
def update_vendor_string(warehouseId, vendorString):
813
    warehouse = get_Warehouse(warehouseId)
813
    warehouse = get_Warehouse(warehouseId)
814
    warehouse.vendorString = vendorString
814
    warehouse.vendorString = vendorString
815
    session.commit()
815
    session.commit()
816
 
816
 
817
def __check_risky_item(item_id):
-
 
818
    ## We should get the list of strings which will identify to the catalog servers
-
 
819
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
-
 
820
    client.validateRiskyStatus(item_id)
-
 
821
    client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
-
 
822
    client = CatalogClient().get_client()
-
 
823
    
-
 
824
def __get_item_from_master(item_id):
817
def __get_item_from_master(item_id):
825
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
818
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
826
    return client.getItem(item_id)
-
 
827
819
    return client.getItem(item_id)
-
 
820
 
-
 
821
def __check_risky_item(item_id, source_id):
-
 
822
    ## We should get the list of strings which will identify to the catalog servers
-
 
823
    if source_id == 1:
-
 
824
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
-
 
825
        client.validateRiskyStatus(item_id)
-
 
826
    if source_id == 2:
-
 
827
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
-
 
828
        client.validateRiskyStatus(item_id)
-
 
829
 
-
 
830
def __get_item_from_source(item_id, source_id):
-
 
831
    if source_id == 1:
-
 
832
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
-
 
833
        return client.getItem(item_id)
-
 
834
    if source_id == 2:
-
 
835
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
-
 
836
        return client.getItem(item_id)
-
 
837
828
838