Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
122 ashish 1
'''
2
Created on 27-Apr-2010
3
 
4
@author: ashish
5
'''
6
from shop2020.model.v1.catalog.impl import DataService
7
from shop2020.utils.Utils import log_entry
8
from shop2020.model.v1.catalog.impl.DataAcessors import add_item, add_warehouse,\
9
    update_inventory, retire_warehouse, retire_item, change_item_status,\
635 rajveer 10
    get_item, get_all_items, get_all_items_by_status, get_item_inventoy,\
643 chandransh 11
    get_item_availability_for_warehouse, get_item_availability_for_location, get_all_warehouses_by_status,\
122 ashish 12
    get_Warehouse, get_all_warehouses_for_item, get_all_items_for_warehouse,\
766 rajveer 13
    update_item, start_item_on, close_session, \
635 rajveer 14
    retire_item_on, get_item_inventory_by_item_id, get_items_by_catalog_id,\
1308 chandransh 15
    get_best_deals, get_best_deals_catalog_ids, get_best_deals_count, get_best_sellers, get_latest_arrivals, get_latest_arrivals_catalog_ids, get_latest_arrivals_count,\
635 rajveer 16
    is_active, get_best_sellers_catalog_ids, get_best_sellers_count, put_category_object,\
871 chandransh 17
    get_category_object, mark_item_as_content_complete,\
1341 chandransh 18
    reserve_item_in_warehouse, reduce_reservation_count, generate_new_entity_id,\
2116 ankur.sing 19
    get_all_item_pricing, add_vendor_pricing, \
2035 rajveer 20
    get_item_pricing, get_category, get_all_categories, add_category,\
2116 ankur.sing 21
    get_item_status_description, get_all_vendors, check_vendor_item_mapping,\
2286 ankur.sing 22
    get_item_mappings, add_vendor_item_mapping, check_similar_item,\
2809 rajveer 23
    change_risky_flag, get_items_by_vendor_category, get_risky_items,\
3086 rajveer 24
    get_similar_items_catalog_ids, add_product_notification,\
3325 chandransh 25
    send_product_notifications, update_inventory_history
122 ashish 26
from shop2020.model.v1.catalog.impl.Convertors import to_t_item,\
2065 ankur.sing 27
    to_t_item_inventory, to_t_warehouse, to_t_vendor_item_pricing, to_t_category,\
2116 ankur.sing 28
    to_t_vendor, to_t_vendor_item_mapping
122 ashish 29
from shop2020.thriftpy.model.v1.catalog.ttypes import status,\
30
    InventoryServiceException
599 chandransh 31
from shop2020.config.client.ConfigClient import ConfigClient
122 ashish 32
 
33
 
34
class InventoryServiceHandler:
35
    '''
36
    classdocs
37
    '''
599 chandransh 38
 
3187 rajveer 39
    def __init__(self, dbname='catalog', db_hostname='localhost'):
122 ashish 40
        '''
41
        Constructor
42
        '''
3187 rajveer 43
        DataService.initialize(dbname, db_hostname)
599 chandransh 44
        try:
621 chandransh 45
            config_client = ConfigClient()
46
            self.latest_arrivals_limit = int(config_client.get_property("LATEST_ARRIVALS_LIMIT"));
47
            self.best_sellers_limit = int(config_client.get_property("BEST_SELLERS_LIMIT"))
599 chandransh 48
        except:
621 chandransh 49
            self.latest_arrivals_limit = 50
50
            self.best_sellers_limit = 50
122 ashish 51
 
52
    #DONE
53
    def addItem(self, item):
54
        """
55
        Availability and inventory attributes
56
 
57
        Parameters:
58
         - item
59
        """
60
        log_entry(self, "addItem called")
785 rajveer 61
        try:
62
            return add_item(item)
63
        finally:
64
            close_session()
122 ashish 65
 
66
    def addWarehouse(self, warehouse):
67
        """
68
        Parameters:
69
         - warehouse
70
        """
71
        log_entry(self, "addWarehouse called")
785 rajveer 72
        try:
73
            return add_warehouse(warehouse)
74
        finally:
75
            close_session()
122 ashish 76
 
3325 chandransh 77
    def updateInventoryHistory(self, warehouse_id, timestamp, availability):
78
        """
79
        Stores the incremental warehouse updates of items.
80
 
81
        Parameters:
82
         - warehouse_id
83
         - timestamp
84
         - availability
85
        """
86
        try:
87
            return update_inventory_history(warehouse_id, timestamp, availability)
88
        finally:
89
            close_session()
483 rajveer 90
 
91
    def updateInventory(self, warehouse_id, timestamp, availability):
122 ashish 92
        """
93
        Parameters:
94
         - warehouse_id
95
         - timestamp
483 rajveer 96
         - availability
122 ashish 97
        """
98
        log_entry(self, "update Inventory called")
785 rajveer 99
        try:
100
            return update_inventory(warehouse_id, timestamp, availability)
101
        finally:
102
            close_session()
103
 
104
 
635 rajveer 105
    def isActive(self, item_id):
563 chandransh 106
        """
107
        Parameters:
635 rajveer 108
         - item_id
563 chandransh 109
        """
785 rajveer 110
        try:
111
            return is_active(item_id)
112
        finally:
113
            close_session()
122 ashish 114
 
2035 rajveer 115
    def getItemStatusDescription(self, itemId):
116
        """
117
        Parameters:
118
         - itemId
119
        """
120
        try:
121
            return get_item_status_description(itemId)
122
        finally:
123
            close_session()
124
 
122 ashish 125
    def retireWarehouse(self, warehouse_id):
126
        """
127
        Parameters:
128
         - warehouse_id
129
        """
130
        log_entry(self, "retire warehouse called")
785 rajveer 131
        try:
132
            return retire_warehouse(warehouse_id)
133
        finally:
134
            close_session()
135
 
122 ashish 136
 
137
    def retireItem(self, item_id):
138
        """
139
        Parameters:
140
        - item_id
141
        """
142
        log_entry(self, "retire item called")
785 rajveer 143
        try:
144
            return retire_item(item_id)
145
        finally:
146
            close_session()
122 ashish 147
 
148
    def startItemOn(self, item_id, timestamp):
149
        """
150
        Parameters:
151
         - item_id
152
         - timestamp
153
        """
785 rajveer 154
        try:
155
            start_item_on(item_id, timestamp)
156
        finally:
157
            close_session()
122 ashish 158
 
159
    def retireItemOn(self, item_id, timestamp):
160
        """
161
        Parameters:
162
         - item_id
163
         - timestamp
164
        """
785 rajveer 165
        try:
166
            retire_item_on(item_id, timestamp)
167
        finally:
168
            close_session()
122 ashish 169
 
170
    def changeItemStatus(self, item_id, timestamp, newstatus):
171
        """
172
        Parameters:
173
         - item_id
174
         - timestamp
175
         - newstatus
176
        """
177
        log_entry(self, "change item status called")
785 rajveer 178
        try:
179
            return change_item_status(item_id, newstatus)
180
        finally:
181
            close_session()
122 ashish 182
 
785 rajveer 183
 
122 ashish 184
    def getItem(self, item_id):
185
        """
186
        Parameters:
187
         - item_id
188
        """
189
        log_entry(self, "item requested")
785 rajveer 190
        try:
2065 ankur.sing 191
            item = to_t_item( get_item(item_id))
192
            return item
785 rajveer 193
        finally:
194
            close_session()
379 ashish 195
 
635 rajveer 196
    def getItemsByCatalogId(self, catalog_item_id):
379 ashish 197
        """
198
        Parameters:
199
        - catalog_item_id
200
        """
386 ashish 201
        log_entry(self, "item requested")
766 rajveer 202
        try:
203
            return get_items_by_catalog_id(catalog_item_id)
204
        finally:
205
            close_session()
122 ashish 206
 
483 rajveer 207
 
122 ashish 208
    def getAllItems(self, isActive):
209
        """
210
        Parameters:
211
         - isActive
212
        """
213
        log_entry(self, "all items requested")
766 rajveer 214
        try:
215
            items = get_all_items(isActive)
216
            ret_items = []
217
            for item in items:
218
                if item:
219
                    ret_items.append(to_t_item(item))
220
            return ret_items
221
        finally:
222
            close_session()
223
 
122 ashish 224
    def getAllItemsByStatus(self, itemStatus):
225
        """
226
        Parameters:
227
         - itemStatus
228
        """
229
        log_entry(self, "all items requested")
766 rajveer 230
        try:
231
            items = get_all_items_by_status(itemStatus)
232
            ret_items = []
233
            for item in items:
234
                if item:
235
                    ret_items.append(to_t_item(item))
236
            return ret_items
237
        finally:
238
            close_session()
122 ashish 239
 
240
    def getItemInventory(self, item_id):
241
        """
242
        Parameters:
243
        - item_id
244
        """
245
        log_entry(self, "item inventory requested")
766 rajveer 246
        try:
247
            inventory = get_item_inventoy(item_id)
248
            return to_t_item_inventory(inventory, item_id)
249
        finally:
250
            close_session()
122 ashish 251
 
635 rajveer 252
    def getItemInventoryByItemId(self, item_id):
253
        """
254
        Parameters:
255
         - item_id
256
        """
257
        log_entry(self, "item inventory requested")
766 rajveer 258
        try:
259
            inventory = get_item_inventory_by_item_id(item_id)
260
            return to_t_item_inventory(inventory, item_id)
261
        finally:
262
            close_session()
635 rajveer 263
 
264
    '''
379 ashish 265
    def getItemInventoryByCatalogId(self, item_id):
266
        """
267
        Parameters:
268
         - item_id
269
        """
383 ashish 270
        log_entry(self, "item inventory requested")
271
        inventory = get_item_inventory_by_catalog_id(item_id)
272
        return to_t_item_inventory(inventory, item_id)
635 rajveer 273
    '''
274
 
379 ashish 275
 
643 chandransh 276
    def getItemAvailabilityAtLocation(self, warehouse_loc, item_id):
277
        """
278
        Returns the id of the warehouse with the largest inventory of the item and the inventory size. The size of list will always be 2.
279
 
280
        Parameters:
281
         - warehouse_loc
282
         - item_id
283
        """
766 rajveer 284
        try:
285
            return get_item_availability_for_location(warehouse_loc, item_id)
286
        finally:
287
            close_session()
288
 
122 ashish 289
    def getItemAvailibilityAtWarehouse(self, warehouse_id, item_id):
290
        """
291
        Parameters:
292
         - warehouse_id
293
         - item_id
294
        """
295
        log_entry(self, "item availability at warehouse requested")
766 rajveer 296
        try:
297
            return get_item_availability_for_warehouse(warehouse_id, item_id)
298
        finally:
299
            close_session()
300
 
2080 rajveer 301
    def markItemAsContentComplete(self, entityId, category, brand, modelName, modelNumber):
302
        """
303
        Parameters:
304
         - entityId
305
         - category
306
         - brand
307
         - modelName
308
         - modelNumber
309
        """
310
        try:
311
            return mark_item_as_content_complete(entityId, category, brand, modelName, modelNumber)
312
        finally:
313
            close_session()
2075 rajveer 314
 
315
 
122 ashish 316
    def getItemInventoryHistory(self, id, item_id, warehouse_id, from_date, to_date):
317
        """
318
        Parameters:
319
         - id
320
         - item_id
321
         - warehouse_id
322
         - from_date
323
         - to_date
324
        """
325
        pass
326
 
327
    def getAllWarehouses(self, isActive):
328
        """
329
        Parameters:
330
        - isActive
331
        """
766 rajveer 332
        try:
333
            if isActive:
334
                warehouses = get_all_warehouses_by_status(status.ACTIVE)
335
            else:
336
                warehouses = get_all_warehouses_by_status(None)
337
 
338
            ret_warehouses = []
339
 
340
            for warehouse in warehouses:
341
                ret_warehouses.append(to_t_warehouse(warehouse))
342
            return ret_warehouses
343
        finally:
344
            close_session()
345
 
122 ashish 346
    def getWarehouse(self, warehouse_id):
347
        """
348
        Parameters:
349
         - warehouse_id
350
        """
351
        log_entry(self, "get warehouse call")
766 rajveer 352
        try:
353
            warehouse = get_Warehouse(warehouse_id)
354
            if warehouse:
355
                return to_t_warehouse(warehouse)
356
            else:
357
                raise InventoryServiceException(101, "no such warehouse")
358
        finally:
359
            close_session()
360
 
122 ashish 361
    def getAllWarehousesForItem(self, item_id):
362
        """
363
        Parameters:
364
         - item_id
365
        """
366
        log_entry(self, "getting all warehouses for item")
766 rajveer 367
        try:
368
            all_warehouses = get_all_warehouses_for_item(item_id)
369
            t_warehouses = []
370
            for warehouse in all_warehouses:
371
                t_warehouses.append(to_t_warehouse(warehouse))
372
            return t_warehouses
373
        finally:
374
            close_session()
375
 
122 ashish 376
    def getAllItemsForWarehouse(self, warehouse_id):
377
        """
378
        Parameters:
379
         - warehouse_id
380
        """
381
        log_entry(self, "getting all items for warehouse")
766 rajveer 382
        try:
383
            all_items = get_all_items_for_warehouse(warehouse_id)
384
            t_items = []
385
            for item in all_items:
386
                t_items.append(to_t_item(item))
387
            return t_items
388
        finally:
389
            close_session()
871 chandransh 390
 
391
    def reserveItemInWarehouse(self, itemId, warehouseId, quantity):
392
        """
393
        Increases the reservation count for an item in a warehouse. Should always succeed normally.
394
 
395
        Parameters:
396
         - itemId
397
         - warehouseId
398
        """
399
        log_entry(self, "reserveItemInWarehouse called")
400
        try:
401
            return reserve_item_in_warehouse(itemId, warehouseId, quantity)
402
        finally:
403
            close_session()
404
 
405
    def reduceReservationCount(self, itemId, warehouseId, quantity):
406
        """
407
        Decreases the reservation count for an item in a warehouse. Should always succeed normally.
408
 
409
        Parameters:
410
         - itemId
411
         - warehouseId
412
        """
413
        log_entry(self, "reduceReservationCount called")
414
        try:
415
            return reduce_reservation_count(itemId, warehouseId, quantity)
416
        finally:
417
            close_session()
766 rajveer 418
 
122 ashish 419
    def updateItem(self, item):
420
        """
421
        Parameters:
422
         - item
423
        """
424
        log_entry(self, "addItem called")
766 rajveer 425
        try:
426
            return update_item(item)
427
        finally:
428
            close_session()
429
 
626 chandransh 430
    def getBestSellers(self, start_index=0, total_items=None, category=-1):
766 rajveer 431
        try:
432
            if total_items is None:
433
                total_items = self.best_sellers_limit
434
            stop_index = start_index + total_items
435
            return get_best_sellers(start_index, stop_index, category)
436
        finally:
437
            close_session()
438
 
1926 rajveer 439
    def getBestSellersCatalogIds(self, start_index, total_items, brand, category=-1):
548 rajveer 440
        """
441
        Parameters:
442
         - beginIndex
443
         - totalItems
444
        """
766 rajveer 445
        try:
446
            if total_items is None:
447
                total_items = self.best_sellers_limit
448
            stop_index = start_index + total_items
1926 rajveer 449
            return get_best_sellers_catalog_ids(start_index, stop_index, brand, category)
766 rajveer 450
        finally:
451
            close_session()
452
 
591 chandransh 453
    def getBestSellersCount(self, ):
766 rajveer 454
        try:
2093 chandransh 455
            return get_best_sellers_count()
766 rajveer 456
        finally:
457
            close_session()
458
 
591 chandransh 459
    def getBestDeals(self,):
766 rajveer 460
        try:
461
            return get_best_deals()
462
        finally:
463
            close_session()
464
 
1926 rajveer 465
    def getBestDealsCatalogIds(self, start_index, total_items, brand,category=-1):
548 rajveer 466
        """
467
        Parameters:
468
         - beginIndex
469
         - totalItems
470
        """
766 rajveer 471
        try:
472
            stop_index = start_index + total_items
1926 rajveer 473
            return get_best_deals_catalog_ids(start_index, stop_index, brand, category)
766 rajveer 474
        finally:
475
            close_session()
476
 
591 chandransh 477
    def getBestDealsCount(self, ):
766 rajveer 478
        try:
479
            return get_best_deals_count()
480
        finally:
481
            close_session()
482
 
591 chandransh 483
    def getLatestArrivals(self,):
766 rajveer 484
        try:
485
            return get_latest_arrivals(self.latest_arrivals_limit)
486
        finally:
487
            close_session()
2975 chandransh 488
 
489
    def getLatestArrivalsCatalogIds(self, beginIndex, totalItems, brand, categories):
548 rajveer 490
        """
2975 chandransh 491
        Returns the list of catalog ids of latest arrivals in the given categories of the given brand.
492
        To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
493
 
548 rajveer 494
        Parameters:
495
         - beginIndex
496
         - totalItems
2975 chandransh 497
         - brand
498
         - categories
548 rajveer 499
        """
766 rajveer 500
        try:
2975 chandransh 501
            if beginIndex > self.latest_arrivals_limit:
766 rajveer 502
                return []
2975 chandransh 503
            stopIndex = beginIndex + totalItems
504
            if stopIndex > self.latest_arrivals_limit:
505
                stopIndex = self.latest_arrivals_limit
506
            return get_latest_arrivals_catalog_ids(beginIndex, stopIndex, brand, categories)
766 rajveer 507
        finally:
508
            close_session()
509
 
591 chandransh 510
    def getLatestArrivalsCount(self, ):
766 rajveer 511
        try:
512
            return get_latest_arrivals_count(self.latest_arrivals_limit)
513
        finally:
514
            close_session()
591 chandransh 515
 
1334 chandransh 516
    def getItemPricing(self, itemId, warehouseId):
517
        """
518
        Returns the pricing information of an item associated with the vendor of the given warehouse.
519
        Raises an exception if either the item, vendor or the associated pricing information can't be found.
520
 
521
        Parameters:
522
         - itemId
523
         - warehouseId
524
        """
1341 chandransh 525
        try:
1347 chandransh 526
            return to_t_vendor_item_pricing(get_item_pricing(itemId, warehouseId))
1341 chandransh 527
        finally:
528
            close_session()
1991 ankur.sing 529
 
530
 
531
    def getAllItemPricing(self, itemId):
532
        """
533
        Returns list of the pricing information of an item associated an item.
534
        Raises an exception if the item can't be found.
535
 
536
        Parameters:
537
         - itemId
538
        """
539
        try:
540
            return [to_t_vendor_item_pricing(vid) for vid in get_all_item_pricing(itemId)]
541
        finally:
542
            close_session()
1334 chandransh 543
 
1155 rajveer 544
    def generateNewEntityID(self, ):
545
        try:
546
            return generate_new_entity_id()
547
        finally:
548
            close_session()
549
 
635 rajveer 550
    def putCategoryObject(self, object):
551
        """
552
        Parameters:
553
         - object
554
        """
766 rajveer 555
        try:
556
            return put_category_object(object)
557
        finally:
558
            close_session()
559
 
635 rajveer 560
    def getCategoryObject(self, ):
766 rajveer 561
        try:
562
            return get_category_object()
563
        finally:
564
            close_session()
1970 rajveer 565
 
566
    def addCategory(self, category):
567
        """
568
        Parameters:
569
         - category
570
        """
571
        try:
572
            return add_category(category)
573
        finally:
574
            close_session()
575
 
576
    def getCategory(self, id):
577
        """
578
        Parameters:
579
         - id
580
        """
581
        try:
582
            return to_t_category(get_category(id))
583
        finally:
584
            close_session()
585
 
586
    def getAllCategories(self, ):
587
        try:
588
            categories = get_all_categories()
589
            return [to_t_category(category) for category in categories]
590
        finally:
591
            close_session()
592
 
593
 
2116 ankur.sing 594
    def addVendorItemPricing(self, vendorItemPricing):
1991 ankur.sing 595
        """
2116 ankur.sing 596
        Adds vendor prices corresponding to the item. If pricing already exists then updates the prices. 
1991 ankur.sing 597
        Raises an exception if either the item or vendor can't be found corresponding to their ids.
598
 
599
        Parameters:
600
         - vendorItemPricing
601
        """
602
        log_entry(self, "updateVendorItemPricing called")
603
        try:
2116 ankur.sing 604
            return add_vendor_pricing(vendorItemPricing)
1991 ankur.sing 605
        finally:
606
            close_session()
607
 
2065 ankur.sing 608
    def getAllVendors(self, ):
609
        """
610
        Return list of all vendors
611
        """
612
        return [to_t_vendor(v) for v in get_all_vendors()]
2116 ankur.sing 613
 
614
    def itemExists(self, productGroup, brand, modelNumber, color, vendorId, category):
615
        try:
616
            return check_vendor_item_mapping(productGroup, brand, modelNumber, color, vendorId, category)
617
        finally:
618
            close_session()
2065 ankur.sing 619
 
2358 ankur.sing 620
    def addVendorItemMapping(self, key, vendorItemMapping):
2116 ankur.sing 621
        """
2358 ankur.sing 622
        Adds VendorItemMapping. Updates VendorItemMapping if exists corresponding to the item key.
2116 ankur.sing 623
 
624
        Parameters:
2358 ankur.sing 625
         - key
2116 ankur.sing 626
         - vendorItemMapping
627
        """
628
        log_entry(self, "addVendorItemMapping called")
629
        try:
2358 ankur.sing 630
            return add_vendor_item_mapping(key, vendorItemMapping)
2116 ankur.sing 631
        finally:
632
            close_session()
633
 
634
    def getVendorItemMappings(self, itemId):
635
        """
636
        Returns the list of vendor item mapping corresponding to itemId passed as parameter.
637
        Raises an exception if item not found corresponding to itemId
638
 
639
        Parameters:
640
         - itemId
641
        """
642
        try:
2120 ankur.sing 643
            item_mappings = get_item_mappings(itemId)
644
            return [to_t_vendor_item_mapping(vim) for vim in item_mappings]
2116 ankur.sing 645
        finally:
646
            close_session()
647
 
648
    def checkSimilarItem(self, productGroup, brand, modelNumber, color):
649
        """
650
        Checks if similar item exists (with same ProductGroup, Brand, ModelNumber, Color)
651
        If yes, returns the itemId else returns 0
652
 
653
        Parameters:
654
         - productGroup
655
         - brand
656
         - modelNumber
657
         - color
658
        """
659
        try:
660
            return check_similar_item(productGroup, brand, modelNumber, color)
661
        finally:
662
            close_session()
663
 
2286 ankur.sing 664
    def changeItemRiskyFlag(self, itemId, risky):
665
        """
666
        Marks/Unmarks an item as risky. This flag is used for automatic marking of an item as INACTIVE in case of zero inventory.
667
 
668
        Parameters:
669
         - itemId
670
         - risky
671
        """
672
        try:
673
            change_risky_flag(itemId, risky)
674
        finally:
675
            close_session()
2116 ankur.sing 676
 
2358 ankur.sing 677
    def getItemsByVendorCategory(self, vendorCategory):
678
        """
679
        Return list of items filtered by vendor category.
680
        Raises exception if vendorCategory is null.
681
 
682
        Parameters:
683
         - vendorCategory
684
        """
685
        try:
686
            return [to_t_item(item) for item in get_items_by_vendor_category(vendorCategory)]
687
        finally:
688
            close_session()
689
 
690
    def getItemsByRiskyFlag(self, ):
691
        """
692
        Returns list of items marked as risky.
693
        """
694
        try:
695
            return [to_t_item(item) for item in get_risky_items()]
696
        finally:
697
            close_session()
2809 rajveer 698
 
699
    def getSimilarItemsCatalogIds(self, beginIndex, totalItems, itemId):
700
        """
701
        Returns list of catalog ids of items with same similarity index as of the given itemId
702
 
703
        Parameters:
704
         - beginIndex
705
         - totalItems
706
         - itemId
707
        """
708
        try:
709
            return get_similar_items_catalog_ids(beginIndex, beginIndex+totalItems, itemId)
710
        finally:
711
            close_session()
3079 rajveer 712
 
713
    def addProductNotification(self, itemId, email):
714
        """
715
        Add user requests for out of stock items. Once user will ask for notify me an entry will
716
 
717
        Parameters:
718
        - itemId
719
        - email
720
        """
721
        try:
722
            return add_product_notification(itemId, email)
723
        finally:
724
            close_session()
2358 ankur.sing 725
 
3086 rajveer 726
    def sendProductNotifications(self, ):
727
        """
728
        Send the product notifications to the users for items which has stock.
729
        """
730
        try:
731
            return send_product_notifications()
732
        finally:
733
            close_session()
766 rajveer 734
    def closeSession(self, ):
735
        close_session()