Subversion Repositories SmartDukaan

Rev

Rev 6857 | Rev 7281 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5944 mandeep.dh 1
'''
2
Created on 27-Apr-2010
3
 
4
@author: ashish
5
'''
6
from shop2020.config.client.ConfigClient import ConfigClient
7
from shop2020.model.v1.inventory.impl import DataService
5957 mandeep.dh 8
from shop2020.model.v1.inventory.impl.Convertors import to_t_item_inventory, \
6821 amar.kumar 9
    to_t_warehouse, to_t_vendor_item_pricing, to_t_vendor, to_t_vendor_item_mapping, \
6832 amar.kumar 10
    to_t_item_stock_purchase_params, to_t_oos_status
5944 mandeep.dh 11
from shop2020.model.v1.inventory.impl.DataAcessors import add_warehouse, \
12
    update_inventory, retire_warehouse, get_item_availability_for_warehouse, \
13
    get_item_availability_for_location, get_all_warehouses_by_status, get_Warehouse, \
5957 mandeep.dh 14
    get_all_items_for_warehouse, close_session, add_vendor, \
15
    get_item_inventory_by_item_id, reserve_item_in_warehouse, \
16
    reduce_reservation_count, get_all_item_pricing, add_vendor_pricing, \
17
    get_item_pricing, get_all_vendors, get_item_mappings, add_vendor_item_mapping, \
18
    update_inventory_history, is_alive, add_inventory, add_bad_inventory, \
19
    mark_missed_inventory_updates_as_processed, update_vendor_string, \
20
    get_item_keys_to_be_processed, reset_availability, get_shipping_locations, \
5944 mandeep.dh 21
    initialize, get_inventory_snapshot, clear_item_availability_cache, \
5987 rajveer 22
    reset_availability_for_warehouse, get_vendor, get_pending_orders_inventory, \
6531 vikram.rag 23
    is_order_billable, get_our_warehouse_id_for_vendor, \
24
    get_item_availability_for_our_warehouses, get_monitored_warehouses_for_vendors, \
25
    get_ignored_warehouseids_and_itemids,insert_item_to_ignore_inventory_update_list, \
26
    delete_item_from_ignore_inventory_update_list,get_all_ignored_inventoryupdate_items_count, \
6821 amar.kumar 27
    get_ignored_inventoryupdate_itemids, update_item_stock_purchase_params, \
6857 amar.kumar 28
    get_item_stock_purchase_params, add_oos_status_for_item, \
7149 amar.kumar 29
    get_oos_statuses_for_x_days_for_item, get_non_zero_item_stock_purchase_params, \
30
    get_billable_inventory_and_pending_orders
5944 mandeep.dh 31
from shop2020.model.v1.inventory.impl.DataService import Warehouse, \
32
    MissedInventoryUpdate, VendorItemMapping
5957 mandeep.dh 33
from shop2020.thriftpy.model.v1.inventory.ttypes import \
34
    InventoryServiceException, WarehouseType, InventoryType, \
35
    AvailableAndReservedStock
5944 mandeep.dh 36
from shop2020.utils.Utils import log_entry, to_java_date
37
 
38
class InventoryServiceHandler:
39
    '''
40
    classdocs
41
    '''
42
 
43
    def __init__(self, dbname='catalog', db_hostname='localhost'):
44
        '''
45
        Constructor
6532 amit.gupta 46
u        '''
5944 mandeep.dh 47
        initialize(dbname, db_hostname)
48
        try:
49
            config_client = ConfigClient()
50
            self.latest_arrivals_limit = int(config_client.get_property("LATEST_ARRIVALS_LIMIT"));
51
            self.best_sellers_limit = int(config_client.get_property("BEST_SELLERS_LIMIT"))
52
        except:
53
            self.latest_arrivals_limit = 50
54
            self.best_sellers_limit = 50
55
 
56
    def addWarehouse(self, warehouse):
57
        """
58
        Parameters:
59
         - warehouse
60
        """
61
        log_entry(self, "addWarehouse called")
62
        try:
63
            return add_warehouse(warehouse)
64
        finally:
65
            close_session()
66
 
67
    def updateInventoryHistory(self, warehouse_id, timestamp, availability):
68
        """
69
        Stores the incremental warehouse updates of items.
70
 
71
        Parameters:
72
         - warehouse_id
73
         - timestamp
74
         - availability
75
        """
76
        try:
77
            return update_inventory_history(warehouse_id, timestamp, availability)
78
        finally:
79
            close_session()
80
 
81
    def updateInventory(self, warehouse_id, timestamp, availability):
82
        """
83
        Parameters:
84
         - warehouse_id
85
         - timestamp
86
         - availability
87
        """
88
        log_entry(self, "update Inventory called")
89
        try:
90
            return update_inventory(warehouse_id, timestamp, availability)
91
        finally:
92
            close_session()
93
 
94
    def addInventory(self, itemId, warehouseId, quantity):
95
        """
96
        Add the inventory to existing stock.
97
 
98
        Parameters:
99
         - itemId
100
         - warehouseId
101
         - quantity
102
        """
103
        log_entry(self, "add Inventory called")
104
        try:
105
            return add_inventory(itemId, warehouseId, quantity)
106
        finally:
107
            close_session()
108
 
109
    def retireWarehouse(self, warehouse_id):
110
        """
111
        Parameters:
112
         - warehouse_id
113
        """
114
        log_entry(self, "retire warehouse called")
115
        try:
116
            return retire_warehouse(warehouse_id)
117
        finally:
118
            close_session()
119
 
120
 
121
    def getItemInventoryByItemId(self, item_id):
122
        """
123
        Parameters:
124
         - item_id
125
        """
126
        log_entry(self, "item inventory requested")
127
        try:
128
            inventory = get_item_inventory_by_item_id(item_id)
129
            return to_t_item_inventory(inventory, item_id)
130
        finally:
131
            close_session()
132
 
5978 rajveer 133
    def getItemAvailabilityAtLocation(self, itemId, sourceId):
5944 mandeep.dh 134
        """
135
        Determines the warehouse that should be used to fulfil an order for the given item.
136
        It first checks all the warehouses which are in the logistics location given by the
137
        warehouse_loc parameter. If none of the warehouses there have any inventory, then the
138
        preferred warehouse for the item is used.
139
 
140
        Returns an ordered list of size 4 with following elements in the given order:
141
        1. Logistics location of the warehouse which was finally picked up to ship the order.
142
        2. Id of the warehouse which was finally picked up.
143
        3. Inventory size in the selected warehouse.
144
        4. Expected delay added by the category manager.
145
 
146
        Parameters:
147
         - itemId
5978 rajveer 148
         - sourceId
5944 mandeep.dh 149
        """
150
        try:
5978 rajveer 151
            return get_item_availability_for_location(itemId, sourceId)
5944 mandeep.dh 152
        finally:
153
            close_session()
154
 
155
    def getItemAvailibilityAtWarehouse(self, warehouse_id, item_id):
156
        """
157
        Parameters:
158
         - warehouse_id
159
         - item_id
160
        """
161
        log_entry(self, "item availability at warehouse requested")
162
        try:
163
            return get_item_availability_for_warehouse(warehouse_id, item_id)
164
        finally:
165
            close_session()
6484 amar.kumar 166
 
167
    def getItemAvailabilitiesAtOurWarehouses(self, item_ids):
168
        try:   
169
            return get_item_availability_for_our_warehouses(item_ids)
170
        finally:
171
            close_session()
5944 mandeep.dh 172
 
173
    def getItemInventoryHistory(self, id, item_id, warehouse_id, from_date, to_date):
174
        """
175
        Parameters:
176
         - id
177
         - item_id
178
         - warehouse_id
179
         - from_date
180
         - to_date
181
        """
182
        pass
183
 
184
    def getAllWarehouses(self, isActive):
185
        """
186
        Parameters:
187
        - isActive
188
        """
189
        try:
190
            if isActive:
191
                warehouses = get_all_warehouses_by_status(3)
192
            else:
193
                warehouses = get_all_warehouses_by_status(None)
194
 
195
            ret_warehouses = []
196
 
197
            for warehouse in warehouses:
198
                ret_warehouses.append(to_t_warehouse(warehouse))
199
            return ret_warehouses
200
        finally:
201
            close_session()
202
 
203
    def getWarehouse(self, warehouse_id):
204
        """
205
        Parameters:
206
         - warehouse_id
207
        """
208
        log_entry(self, "get warehouse call")
209
        try:
210
            warehouse = get_Warehouse(warehouse_id)
211
            if warehouse:
212
                return to_t_warehouse(warehouse)
213
            else:
214
                raise InventoryServiceException(101, "no such warehouse: " + str(warehouse_id))
215
        finally:
216
            close_session()
217
 
218
    def getAllItemsForWarehouse(self, warehouse_id):
219
        """
220
        Parameters:
221
         - warehouse_id
222
        """
223
        log_entry(self, "getting all items for warehouse")
224
        try:
225
            all_items = get_all_items_for_warehouse(warehouse_id)
226
            t_items = []
227
            for item in all_items:
228
                t_items.append(item.id)
229
            return t_items
230
        finally:
231
            close_session()
232
 
5966 rajveer 233
    def isOrderBillable(self, itemId, warehouseId, sourceId, orderId):
5944 mandeep.dh 234
        """
5966 rajveer 235
        Depending on reservation in the table, verify if we can bill this order or not.
236
 
237
        Parameters:
238
         - itemId
239
         - warehouseId
240
         - sourceId
241
         - orderId
242
        """
243
        try:
244
            return is_order_billable(itemId, warehouseId, sourceId, orderId)
245
        finally:
246
            close_session()
247
 
248
    def reserveItemInWarehouse(self, itemId, warehouseId, sourceId, orderId, createdTimestamp, promisedShippingTimestamp, quantity):
249
        """
5944 mandeep.dh 250
        Increases the reservation count for an item in a warehouse. Should always succeed normally.
251
 
252
        Parameters:
253
         - itemId
254
         - warehouseId
255
        """
256
        log_entry(self, "reserveItemInWarehouse called")
257
        try:
5966 rajveer 258
            return reserve_item_in_warehouse(itemId, warehouseId, sourceId, orderId, createdTimestamp, promisedShippingTimestamp, quantity)
5944 mandeep.dh 259
        finally:
260
            close_session()
261
 
5966 rajveer 262
    def reduceReservationCount(self, itemId, warehouseId, sourceId, orderId, quantity):
5944 mandeep.dh 263
        """
264
        Decreases the reservation count for an item in a warehouse. Should always succeed normally.
265
 
266
        Parameters:
267
         - itemId
268
         - warehouseId
269
        """
270
        log_entry(self, "reduceReservationCount called")
271
        try:
5966 rajveer 272
            return reduce_reservation_count(itemId, warehouseId, sourceId, orderId, quantity)
5944 mandeep.dh 273
        finally:
274
            close_session()
275
 
276
    def getItemPricing(self, itemId, vendorId):
277
        """
278
        Returns the pricing information of an item associated with the vendor of the given warehouse.
279
        Raises an exception if either the item, vendor or the associated pricing information can't be found.
280
 
281
        Parameters:
282
         - itemId
283
         - warehouseId
284
        """
285
        try:
286
            return to_t_vendor_item_pricing(get_item_pricing(itemId, vendorId))
287
        finally:
288
            close_session()
289
 
290
 
291
    def getAllItemPricing(self, itemId):
292
        """
293
        Returns list of the pricing information of an item associated an item.
294
        Raises an exception if the item can't be found.
295
 
296
        Parameters:
297
         - itemId
298
        """
299
        try:
300
            return [to_t_vendor_item_pricing(vid) for vid in get_all_item_pricing(itemId)]
301
        finally:
302
            close_session()
303
 
304
    def addVendorItemPricing(self, vendorItemPricing):
305
        """
306
        Adds vendor prices corresponding to the item. If pricing already exists then updates the prices. 
307
        Raises an exception if either the item or vendor can't be found corresponding to their ids.
308
 
309
        Parameters:
310
         - vendorItemPricing
311
        """
312
        log_entry(self, "updateVendorItemPricing called")
313
        try:
314
            return add_vendor_pricing(vendorItemPricing)
315
        finally:
316
            close_session()
317
 
318
    def getVendor(self, vendorId):
319
        """
320
        Return a vendor for id
321
        """
322
        try:
323
            return to_t_vendor(get_vendor(vendorId))
324
        finally:
325
            close_session()
326
 
327
 
328
    def getAllVendors(self, ):
329
        """
330
        Return list of all vendors
331
        """
332
        try:
333
            return [to_t_vendor(v) for v in get_all_vendors()]
334
        finally:
335
            close_session()
336
 
337
    def addVendorItemMapping(self, key, vendorItemMapping):
338
        """
339
        Adds VendorItemMapping. Updates VendorItemMapping if exists corresponding to the item key.
340
 
341
        Parameters:
342
         - key
343
         - vendorItemMapping
344
        """
345
        log_entry(self, "addVendorItemMapping called")
346
        try:
347
            return add_vendor_item_mapping(key, vendorItemMapping)
348
        finally:
349
            close_session()
350
 
351
    def getVendorItemMappings(self, itemId):
352
        """
353
        Returns the list of vendor item mapping corresponding to itemId passed as parameter.
354
        Raises an exception if item not found corresponding to itemId
355
 
356
        Parameters:
357
         - itemId
358
        """
359
        try:
360
            item_mappings = get_item_mappings(itemId)
361
            return [to_t_vendor_item_mapping(vim) for vim in item_mappings]
362
        finally:
363
            close_session()
364
 
365
    def isAlive(self, ):
366
        """
367
        For checking weather service is active alive or not. It also checks connectivity with database
368
        """
369
        try:
370
            return is_alive()
371
        finally:
372
            close_session()
373
 
374
    def closeSession(self, ):
375
        """
376
        For closing the open session in sqlalchemy
377
        """
378
        close_session()
379
 
380
    def addVendor(self, vendor):
381
        """
382
        add a new vendor
383
        """
384
        try:
385
            return add_vendor(vendor)
386
        finally:
387
            close_session()
388
 
389
    def getWarehouses(self, warehouseType, inventoryType, vendorId, billingWarehouseId, shippingWarehouseId):
390
        """
391
        This method returns all warehouses for a given warehosueType, inventoryType, vendor, billingWarehouse and shippingWarehouse.
392
        getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 3, 7, 7) would return ours warehouse with GOOD type inventory for vendor 1 for billing warehouse 7 and shipping warehouse 7
393
        getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 3, 7, 7) would return ours warehouse with GOOD type inventory for vendor 3 for billing warehouse 7 and shipping warehouse 7
394
        getWarehouses(null, null, 3, 7, 7) would return all type warehouses with all type inventory for vendor 3 for billing warehouse 7 and shipping warehouse 7
395
        getWarehouses(null, null, 0, 0, 7) would return all type warehouses with all type inventory for all vendors for all billing warehouses at shipping warehouse 7
396
 
397
        Parameters:
398
         - warehouseType
399
         - inventoryType
400
         - vendorId
401
         - billingWarehouseId
402
         - shippingWarehouseId
403
        """
404
        try:
405
            query = Warehouse.query
406
            if warehouseType is not None:
407
                query = query.filter_by(warehouseType = WarehouseType._VALUES_TO_NAMES[warehouseType])
408
            if inventoryType is not None:
409
                query = query.filter_by(inventoryType = InventoryType._VALUES_TO_NAMES[inventoryType])
410
            if vendorId:
411
                query = query.filter_by(vendor_id = vendorId)
412
            if billingWarehouseId:
413
                query = query.filter_by(billingWarehouseId = billingWarehouseId)
414
            if shippingWarehouseId:
415
                query = query.filter_by(shippingWarehouseId = shippingWarehouseId)
416
 
417
            return [to_t_warehouse(w) for w in query.all()]
418
        finally:
419
            close_session()
420
 
421
    def getItemKeysToBeProcessed(self, warehouseId):
422
        """
423
        Returns the list of item keys which need to be processed for a given warehouse.
424
        This is currently used by Support application to send item keys whose inventory needs
425
        to be updated from PLB
426
 
427
        Parameters:
428
         - warehouseId
429
        """
430
        try:
431
            return get_item_keys_to_be_processed(warehouseId)
432
        finally:
433
            close_session()
434
 
435
    def markMissedInventoryUpdatesAsProcessed(self, itemKey, warehouseId):
436
        """
437
        Marks/Deletes missed inventory updates for a given key and warehouse.
438
        This generally happens when updates from PLB are applied on the currentinventorysnapshot for an item
439
 
440
        Parameters:
441
         - itemKey
442
         - warehouseId
443
        """
444
        try:
445
            mark_missed_inventory_updates_as_processed(itemKey, warehouseId)
446
        finally:
447
            close_session()
448
 
449
    def resetAvailability(self, itemKey, vendorId, quantity, warehouseId):
450
        """
451
        Resets availability of an item to the quantity mentioned in a warehouse.
452
 
453
        Parameters:
454
         - itemKey
455
         - vendorId
456
         - quantity
457
         - warehouseId
458
        """
459
        try:
460
            reset_availability(itemKey, vendorId, quantity, warehouseId)
461
        finally:
462
            close_session()
463
 
464
    def resetAvailabilityForWarehouse(self, warehouseId):
465
        """
466
        Resets availability of a warehouse to zero.
467
 
468
        Parameters:
469
         - warehouseId
470
        """
471
        try:
472
            reset_availability_for_warehouse(warehouseId)
473
        finally:
474
            close_session()
475
 
476
    def getIgnoredItemKeys(self, ):
477
        """
478
        Returns all the item key mappings that have been ignored until date. Value of map has the warehouse id
479
        and the timestamp from where alert was raised.
480
        """
481
        try:
482
            itemKeysMap = {}
483
            for key in MissedInventoryUpdate.query.filter_by(isIgnored = 1).all():
484
                itemKeysMap[key.itemKey] = { key.warehouseId : to_java_date(key.timestamp) }
485
 
486
            return itemKeysMap
487
        finally:
488
            close_session()
489
 
490
    def addBadInventory(self, itemId, warehouseId, quantity):
491
        """
492
        Add the BAD type inventory to existing stock.
493
 
494
        Parameters:
495
         - itemId
496
         - warehouseId
497
         - quantity
498
        """
499
        try:
500
            add_bad_inventory(itemId, warehouseId, quantity)
501
        finally:
502
            close_session()
503
 
504
    def getShippingLocations(self, ):
505
        """
506
        Returns all shipping locations
507
        """
508
        try:
509
            return [to_t_warehouse(w) for w in get_shipping_locations()]
510
        finally:
511
            close_session()
512
 
513
    def getAllVendorItemMappings(self, ):
514
        """
515
        Fetches all the vendor item mappings present.
516
        """
517
        try:
518
            return [to_t_vendor_item_mapping(m) for m in VendorItemMapping.query.all()]
519
        finally:
520
            close_session()
521
 
522
    def getInventorySnapshot(self, warehouseId):
523
        """
524
        Gets items' inventory for a warehouse
525
        If warehouse is passed as zero, items' inventory across all warehouses is sent
526
 
527
        Parameters:
528
         - warehouseId
529
        """
530
        try:
531
            resultMap = {}
532
            itemInventoryMap = get_inventory_snapshot(warehouseId)
533
            for key, value in itemInventoryMap.items():
534
                resultMap[key] = to_t_item_inventory(value, key)
535
 
536
            return resultMap
537
        finally:
538
            close_session()
539
 
540
    def clearItemAvailabilityCache(self, ):
541
        """
542
        Clear item availability cache.
543
        """
544
        try:
545
            clear_item_availability_cache()
546
        finally:
547
            close_session()
5957 mandeep.dh 548
 
6096 amit.gupta 549
    def clearItemAvailabilityCacheForItem(self, item_id):
550
        """
551
        Clear item availability cache.
552
        """
553
        try:
554
            clear_item_availability_cache(item_id)
555
        finally:
556
            close_session()
557
 
5957 mandeep.dh 558
    def getPendingOrdersInventory(self, vendorId):
559
        """
560
        Returns a list of inventory stock for items for which there are pending orders for the given vendor.
561
        """
562
        try:
563
            pending_items_inventory = get_pending_orders_inventory(vendorId)
564
            return [AvailableAndReservedStock(itemId = i[0], available=i[1], reserved=i[2], minimumStock=0) for i in pending_items_inventory]
565
        finally:
566
            close_session()
567
 
5944 mandeep.dh 568
    def updateVendorString(self, warehouseId, vendorString):
569
        """
570
        Parameters:
571
         - warehouseId
572
         - vendorString
573
        """
574
        try:
575
            update_vendor_string(warehouseId, vendorString)
576
        finally:
577
            close_session()
6467 amar.kumar 578
    def getOurWarehouseIdForVendor(self, vendorId):
579
        """
580
        Returns warehouseId for our warehouse for a vendor
581
        """    
582
        try:
583
            return get_our_warehouse_id_for_vendor(vendorId)
584
        finally:
6531 vikram.rag 585
            close_session()
586
    def getMonitoredWarehouseForVendors(self, vendorIds):
587
        """
588
        Returns monitored warehouse ids for vendors
589
        """    
590
        try:
591
            return get_monitored_warehouses_for_vendors(vendorIds)
592
        finally:
593
            close_session()
594
    def getIgnoredWarehouseidsAndItemids(self):
595
        """
596
        Returns list of itemid and warehouseId for ignored inventory update
597
        """    
598
        try:
599
            return get_ignored_warehouseids_and_itemids()
600
        finally:
601
            close_session()
602
 
603
    def insertItemtoIgnoreInventoryUpdatelist(self,item_id,warehouse_id):
604
        """
605
        Returns list of itemid and warehouseId for ignored inventory update
606
        """
607
        try:
6532 amit.gupta 608
            return insert_item_to_ignore_inventory_update_list(item_id,warehouse_id)
6531 vikram.rag 609
        finally:
610
            close_session()     
611
    def deleteItemFromIgnoredInventoryUpdateList(self,item_id,warehouse_id):
612
        """
613
        Deletes warehouse and item entry from inventory update ignore list
614
        """
615
        try:
616
            return delete_item_from_ignore_inventory_update_list(item_id,warehouse_id)
617
        finally:
618
            close_session()
619
    def getAllIgnoredInventoryupdateItemsCount(self):
620
        """
621
        Returns all ignored inventory update item count
622
        """
6833 amar.kumar 623
        try:
624
            return get_all_ignored_inventoryupdate_items_count()
625
        finally:
626
            close_session()
6531 vikram.rag 627
 
628
 
629
    def getIgnoredInventoryUpdateItemids(self,offset,limit):
630
        """
631
        Returns all ignored inventory update items
632
        """
6833 amar.kumar 633
        try:
634
            return get_ignored_inventoryupdate_itemids(offset,limit)
635
        finally:
636
            close_session()
6821 amar.kumar 637
    def updateItemStockPurchaseParams(self, item_id, numOfDaysStock, minStockLevel):
638
        """
639
        Update/Add parameters required for heuristic purchase of Items 
6833 amar.kumar 640
        """ 
641
        try:               
642
            update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel)
643
        finally:
644
            close_session()
645
 
6821 amar.kumar 646
    def getItemStockPurchaseParams(self, item_id):
647
        """
648
        Get parameters required for heuristic purchase of Items 
6833 amar.kumar 649
        """ 
650
        try:               
651
            return to_t_item_stock_purchase_params(get_item_stock_purchase_params(item_id))
652
        finally:
653
            close_session()
654
 
6821 amar.kumar 655
    def addOosStatusForItem(self, oosStatusMap, date):
656
        """
657
        Add OOS status for Item 
658
        """
6833 amar.kumar 659
        try:
660
            add_oos_status_for_item(oosStatusMap, date)
661
        finally:
662
            close_session()
663
 
6832 amar.kumar 664
    def getOosStatusesForXDaysForItem(self, itemId, days):
665
        """
666
        Get OOSStatus Objects for "days" number of days 
667
        """
6833 amar.kumar 668
        try:
669
            return [to_t_oos_status(oos) for oos in get_oos_statuses_for_x_days_for_item(itemId, days)]
670
        finally:
6857 amar.kumar 671
            close_session()
672
 
673
    def getNonZeroItemStockPurchaseParams(self):
674
        """
675
        Get All ItemStockPurchaseParam objects where either minStockLevel or minNumOfDaysOfStock is zero 
676
        """
677
        try:
678
            return [to_t_item_stock_purchase_params(ispp) for ispp in get_non_zero_item_stock_purchase_params()]
679
        finally:
7149 amar.kumar 680
            close_session()
681
    def getBillableInventoryAndPendingOrders(self):
682
        """
683
        Returns a list of inventory stock for items for which there are pending orders or have 
684
        billable inventory.
685
        """
686
        try:
687
            items_inventory = get_billable_inventory_and_pending_orders()
688
            return [AvailableAndReservedStock(itemId = i[0], available=i[1], reserved=i[2], minimumStock=0) for i in items_inventory]
689
        finally:
6833 amar.kumar 690
            close_session()