Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
17812 amit.gupta 1
'''
2
Created on 10-May-2010
3
 
4
@author: ashish
5
'''
6
from elixir import *
7
from shop2020.clients.CatalogClient import CatalogClient
8
from shop2020.clients.InventoryClient import InventoryClient
9
from shop2020.clients.LogisticsClient import LogisticsClient
10
from shop2020.clients.PromotionClient import PromotionClient
11
from shop2020.clients.TransactionClient import TransactionClient
12
from shop2020.model.v1 import user
13
from shop2020.model.v1.user.impl.Converters import to_t_cart, to_t_line
14
from shop2020.model.v1.user.impl.Dataservice import Cart, Line, Address, User, \
15
    Discount, InsuranceDetails, PrivateDealUser
16
from shop2020.thriftpy.logistics.ttypes import LogisticsServiceException, \
17
    DeliveryType
18
from shop2020.thriftpy.model.v1.catalog.ttypes import Item, InsurerType
19
from shop2020.thriftpy.model.v1.order.ttypes import Transaction as TTransaction, \
20
    TransactionStatus as TTransactionStatus, Order as TOrder, LineItem as TLineItem, \
21
    OrderStatus, OrderSource
22
from shop2020.thriftpy.model.v1.user.ttypes import CartStatus, LineStatus, \
23
    ShoppingCartException, PromotionException, CartPlus
24
from shop2020.utils.Utils import to_py_date, to_java_date
25
import datetime
26
import json
27
import math
28
import traceback
29
 
30
 
31
 
32
 
33
def get_cart(userId):
34
    user = User.get_by(id=userId)
35
    return user.active_cart
36
 
37
def get_cart_by_id(id):
38
    cart = Cart.get_by(id=id)
39
    return cart
40
 
41
def create_cart():
42
    cart = Cart()
43
    cart.created_on = datetime.datetime.now()
44
    cart.updated_on = datetime.datetime.now()
45
    cart.cart_status = CartStatus.ACTIVE
46
    return cart
47
 
48
def get_carts_between(start_time, end_time, status):
49
    init_time = to_py_date(start_time)
50
    finish_time = to_py_date(end_time)
557 chandransh 51
 
17812 amit.gupta 52
    query = Cart.query
53
    if status:
54
        query = query.filter(Cart.cart_status==status)
55
    if init_time:
56
        query = query.filter(Cart.created_on >= init_time)
57
    if finish_time:
58
        query = query.filter(Cart.created_on <= finish_time)
557 chandransh 59
 
17812 amit.gupta 60
    carts = query.all()
61
    return carts
62
 
63
def get_line(item_id, cart_id, status, single):
64
    #get cart first 
65
    try:
66
        found_cart = Cart.get_by(id=cart_id)
67
    except:
68
        raise ShoppingCartException(101, "cart not found ")
69
    query = Line.query.filter_by(cart = found_cart, item_id = item_id)
557 chandransh 70
 
17812 amit.gupta 71
    if status:
72
        query = query.filter_by(line_status = status)
73
    else:
74
        query = query.filter_by(line_status = LineStatus.LINE_ACTIVE)
75
    try:
76
        if single:
77
            return query.one()
78
        else:
79
            return query.all()
80
    except:
81
        return None
82
 
83
def add_item_to_cart(cart_id, item_id, quantity, sourceId):
84
    if not item_id:
85
        raise ShoppingCartException(101, "item_id cannot be null")
557 chandransh 86
 
17812 amit.gupta 87
    if not quantity:
88
        raise ShoppingCartException(101, "quantity cannot be null")    
89
 
90
    cart = Cart.get_by(id = cart_id)    
91
    if not cart:
92
        raise ShoppingCartException(101, "no cart attached to this id" + str(cart_id))
93
    retval = ""
94
    catalog_client = CatalogClient().get_client()
95
    item = catalog_client.getItemForSource(item_id, sourceId)
96
    dataProtectionInsurer = catalog_client.getPrefferedInsurerForItem(item_id,InsurerType._NAMES_TO_VALUES.get("DATA"))
97
    item_shipping_info = catalog_client.isActive(item_id)
98
    if not item_shipping_info.isActive:
99
        return catalog_client.getItemStatusDescription(item_id)
557 chandransh 100
 
17812 amit.gupta 101
    current_time = datetime.datetime.now()
102
    cart.updated_on = current_time
103
    line = get_line(item_id, cart_id, None,True)
104
    if line:
105
        #change the quantity only
106
        line.insuranceAmount = (line.insuranceAmount/line.quantity) * quantity
107
        line.quantity = quantity
108
        line.updated_on = current_time
109
        line.dataProtectionAmount = (line.dataProtectionAmount/line.quantity) * quantity
110
    else:
111
        line = Line()
112
        line.cart = cart
113
        line.item_id = item_id
114
        line.quantity = quantity
115
        line.created_on = current_time
116
        line.updated_on = current_time
117
        line.actual_price = item.sellingPrice
118
        line.line_status = LineStatus.LINE_ACTIVE
119
        line.insurer = 0
120
        line.insuranceAmount = 0
121
        #DATA INSURER IS SET UPON ADD TO CART
122
        line.dataProtectionInsurer = dataProtectionInsurer
123
    session.commit()
124
    return retval
125
 
126
def delete_item_from_cart(cart_id, item_id):
127
    if not item_id:
128
        raise ShoppingCartException(101, "item_id cannot be null")
129
    cart = Cart.get_by(id = cart_id)
130
    if not cart:
131
        raise ShoppingCartException(101, "no cart attached to this id")
132
    item = get_line(item_id, cart_id, None, True)
133
    count_deleted_discounts = delete_discounts_for_line(item)
134
    item.delete()
135
    current_time = datetime.datetime.now()
136
    cart.updated_on = current_time
137
    session.commit()
138
 
139
def delete_discounts_for_line(item_line):
140
    count_deleted = Discount.query.filter_by(line = item_line).delete()
141
    session.commit()
142
    return count_deleted
143
 
144
def delete_discounts_from_cart(cart_id, cart = None):
145
    if cart is None:
146
        if cart_id is None:
147
            raise ShoppingCartException(101, 'cart_id and cart, both cannot be null')
148
        else:
149
            cart = Cart.get_by(id = cart_id)
3554 varun.gupt 150
 
17812 amit.gupta 151
    if cart.lines:
152
        for line in cart.lines:
153
            delete_discounts_for_line(line)
154
 
155
def save_discounts(discounts):
156
    if not discounts:
157
        raise ShoppingCartException(101, 'discounts be null')
3554 varun.gupt 158
 
17812 amit.gupta 159
    if len(discounts) > 0:
160
        cart = Cart.get_by(id = discounts[0].cart_id)
161
 
162
        for t_discount in discounts:
163
            line = Line.query.filter_by(cart = cart, item_id = t_discount.item_id).first()
164
            if line is not None:
165
                discount = Discount()
166
                discount.line = line
167
                discount.discount = t_discount.discount
168
                discount.quantity = t_discount.quantity
169
                session.commit()
170
 
171
def add_address_to_cart(cart_id, address_id):
172
    if not cart_id:
173
        raise ShoppingCartException(101, "cart id cannot be made null")
557 chandransh 174
 
17812 amit.gupta 175
    if not address_id:
176
        raise ShoppingCartException(101, "address id cannot be made null")
177
 
178
    cart = get_cart_by_id(cart_id)
179
    if not cart:
180
        raise ShoppingCartException(101, "no cart for this id")
181
 
182
    address = Address.get_by(id=address_id)
183
    if not address:
184
        raise ShoppingCartException(101, "No address for this id")
185
 
186
    cart.address_id = address_id
187
    current_time = datetime.datetime.now()
188
    #cart.updated_on = current_time
189
    session.commit()
190
 
191
def add_store_to_cart(cartId, storeId):
192
    if not cartId:
193
        raise ShoppingCartException(101, "cart id cannot be made null")
194
 
195
    cart = get_cart_by_id(cartId)
196
    if not cart:
197
        raise ShoppingCartException(101, "no cart for this id")
198
 
199
    if storeId:
200
        cart.pickupStoreId = storeId
201
    else:
202
        cart.pickupStoreId = None
5555 rajveer 203
 
17812 amit.gupta 204
    session.commit()
205
 
206
def apply_coupon_to_cart(t_cart, coupon_code):
207
    cart = get_cart_by_id(t_cart.id)
208
    if not cart:
209
        raise ShoppingCartException(101, "no cart attached to this id")
210
    pc = PromotionClient().get_client()
211
    for t_line in t_cart.lines:
212
        line = Line.query.filter_by(cart = cart).filter_by(item_id = t_line.itemId).one()
213
        line.discounted_price = None
214
        if not pc.isGiftVoucher(coupon_code):
215
            line.discounted_price = t_line.discountedPrice
216
        #line.dealText = t_line.dealText
217
        #line.freebieId = t_line.freebieId
218
 
219
    cart.total_price = t_cart.totalPrice
220
    cart.discounted_price = t_cart.discountedPrice
221
    cart.coupon_code = coupon_code
222
    session.commit()
223
 
224
def remove_coupon(cart_id):
225
    cart = get_cart_by_id(cart_id)
226
    if not cart:
227
        raise ShoppingCartException(101, "no cart attached to this id")
228
 
229
    #Resetting discounted price of each line in cart to Null
230
    for line in cart.lines:
231
        line.discounted_price = None
232
        line.dealText = None
233
        line.freebieId = None
234
 
235
    delete_discounts_from_cart(cart.id, cart=cart)
236
    cart.discounted_price = None
237
    cart.coupon_code = None
238
    session.commit()
239
 
240
def commit_cart(cart_id, sessionSource, sessionTime, firstSource, firstSourceTime, userId, schemeId, orderSource):   
241
    cart = get_cart_by_id(cart_id)   
242
    #now we have a cart. Need to create a transaction with it
243
    totalCartVal = 0
244
    totalshippingCost = 0
245
    for lineObj in cart.lines:
246
        totalCartVal += lineObj.actual_price * lineObj.quantity
247
    txn = TTransaction()
248
    txn.shoppingCartid = cart_id
249
    txn.customer_id = userId
250
    txn.createdOn = to_java_date(datetime.datetime.now())
251
    txn.transactionStatus = TTransactionStatus.INIT
252
    txn.statusDescription = "New Order"
253
    txn.coupon_code = cart.coupon_code
254
    txn.sessionSource = sessionSource
255
    txn.sessionStartTime = sessionTime
256
    txn.firstSource = firstSource
257
    txn.firstSourceTime = firstSourceTime
258
    txn.emiSchemeId = schemeId
259
    privateDealUser = PrivateDealUser.query.filter(PrivateDealUser.id == userId).filter(PrivateDealUser.isActive==True).first()
260
    if privateDealUser is not None:
261
        if totalCartVal < 500:
262
            totalshippingCost = 100
263
        elif totalCartVal >=500 and totalCartVal<1000:
264
            totalshippingCost = 50
265
    txn.totalShippingCost = totalshippingCost
17470 manish.sha 266
 
17812 amit.gupta 267
    txnOrders = create_orders(cart, userId, orderSource, totalshippingCost, totalCartVal)
268
    shippingCostInOrders = 0
269
    for order in txnOrders:
270
        shippingCostInOrders = shippingCostInOrders + order.shippingCost
576 chandransh 271
 
17812 amit.gupta 272
    diff = totalshippingCost - shippingCostInOrders
18061 manish.sha 273
    txnOrders[0].shippingCost = txnOrders[0].shippingCost + diff
17812 amit.gupta 274
 
275
 
276
    txn.orders = txnOrders
277
 
278
    transaction_client = TransactionClient().get_client()
279
    txn_id = transaction_client.createTransaction(txn)
280
 
281
    privateDealUser = PrivateDealUser.query.filter(PrivateDealUser.id == userId).filter(PrivateDealUser.isActive==True).first()
282
    if privateDealUser is not None and privateDealUser.counter is not None:
283
        privateDealUser.counter.lastPurchasedOn = datetime.datetime.now()
284
    session.commit()
285
 
286
    return txn_id
287
 
288
def create_orders(cart, userId, orderSource, totalshippingCost, totalCartVal):
289
    cart_lines = cart.lines
290
    orders = []
291
    isGv = False
292
    if cart.coupon_code:
6318 rajveer 293
        try:
17812 amit.gupta 294
            pc = PromotionClient().get_client()
295
            isGv = pc.isGiftVoucher(cart.coupon_code)
6318 rajveer 296
        except:
17812 amit.gupta 297
            isGv = False
6318 rajveer 298
 
17812 amit.gupta 299
    insuranceDetails = InsuranceDetails.get_by(addressId = cart.address_id)
6903 anupam.sin 300
 
17812 amit.gupta 301
    for line in cart_lines:
302
        if line.line_status == LineStatus.LINE_ACTIVE:
303
            quantity_remaining_for_order = line.quantity
3554 varun.gupt 304
 
17812 amit.gupta 305
            for discount in line.discounts:
306
                #i = 0
307
                #while i < discount.quantity:
308
                t_line_item = create_line_item(line, line.actual_price if isGv else (line.actual_price - discount.discount), line.quantity)
309
                t_order = create_order(userId, cart.address_id, t_line_item, cart.pickupStoreId, discount.discount if isGv else 0, line.insurer, (line.insuranceAmount/line.quantity), insuranceDetails,line.dataProtectionInsurer,(line.dataProtectionAmount)/line.quantity, orderSource, line.freebieId, totalshippingCost, totalCartVal)
310
                orders.append(t_order)
311
                    #i += 1
312
                quantity_remaining_for_order -= discount.quantity
313
 
314
            if quantity_remaining_for_order > 0:
315
                t_line_item = create_line_item(line, line.actual_price, quantity_remaining_for_order)
316
                t_order = create_order(userId, cart.address_id, t_line_item, cart.pickupStoreId, 0, line.insurer, (line.insuranceAmount/line.quantity), insuranceDetails, line.dataProtectionInsurer,(line.dataProtectionAmount)/line.quantity, orderSource, line.freebieId, totalshippingCost, totalCartVal)
317
                orders.append(t_order)
318
            '''
319
            i = 0
320
            while i < quantity_remaining_for_order:
321
                t_line_item = create_line_item(line, line.actual_price)
322
                t_order = create_order(userId, cart.address_id, t_line_item, cart.pickupStoreId, 0, line.insurer, (line.insuranceAmount/line.quantity), insuranceDetails, line.dataProtectionInsurer,(line.dataProtectionAmount)/line.quantity, orderSource, line.freebieId)
323
                orders.append(t_order)
324
                i += 1
325
            '''
326
    return orders
327
 
328
def create_order(userId, address_id, t_line_item, pickupStoreId, gvAmount, insurer, insuranceAmount, insuranceDetails, dataProtectionInsurer, dataProtectionAmount, orderSource, freebieId, totalshippingCost, totalCartVal):
329
    user = User.get_by(id=userId)
330
    address = Address.get_by(id=address_id)
331
    t_order = TOrder()
557 chandransh 332
 
17812 amit.gupta 333
    t_order.customer_id = user.id
334
    t_order.customer_email = user.email
576 chandransh 335
 
17812 amit.gupta 336
    t_order.customer_name = address.name
337
    t_order.customer_pincode = address.pin
338
    t_order.customer_address1 = address.line_1
339
    t_order.customer_address2 = address.line_2
340
    t_order.customer_city = address.city
341
    t_order.customer_state = address.state
342
    t_order.customer_mobilenumber = address.phone
576 chandransh 343
 
17812 amit.gupta 344
    t_order.total_amount = t_line_item.total_price + insuranceAmount + dataProtectionAmount
345
    t_order.gvAmount = gvAmount
1976 varun.gupt 346
 
17812 amit.gupta 347
    t_order.total_weight = t_line_item.total_weight
348
    t_order.lineitems = [t_line_item]
576 chandransh 349
 
17812 amit.gupta 350
    t_order.status = OrderStatus.PAYMENT_PENDING
351
    t_order.statusDescription = "Payment Pending"
352
    t_order.created_timestamp = to_java_date(datetime.datetime.now())
576 chandransh 353
 
17812 amit.gupta 354
    t_order.pickupStoreId = pickupStoreId 
355
    t_order.insuranceAmount = insuranceAmount 
356
    t_order.insurer = insurer
357
    if insuranceDetails:
358
        t_order.dob = insuranceDetails.dob
359
        t_order.guardianName = insuranceDetails.guardianName
7190 amar.kumar 360
 
17812 amit.gupta 361
    catalog_client = CatalogClient().get_client()
11669 amit.gupta 362
 
17812 amit.gupta 363
    if freebieId is None:
364
        freebie_item_id = catalog_client.getFreebieForItem(t_line_item.item_id)
365
        if freebie_item_id:
366
            t_order.freebieItemId = freebie_item_id
367
    else:
368
        freebie_item_id = None if freebieId == 0 else freebieId  
369
    t_order.source = orderSource
370
    t_order.dataProtectionInsurer = dataProtectionInsurer
371
    t_order.dataProtectionAmount = dataProtectionAmount
372
    t_order.shippingCost = round((t_line_item.total_price*totalshippingCost)/totalCartVal, 0)
373
    return t_order
576 chandransh 374
 
17812 amit.gupta 375
def create_line_item(line, final_price, quantity=1):
376
    inventory_client = CatalogClient().get_client()
377
    item = inventory_client.getItem(line.item_id)
378
    t_line_item = TLineItem()
379
    t_line_item.productGroup = item.productGroup
380
    t_line_item.brand = item.brand
381
    t_line_item.model_number = item.modelNumber
382
    if item.color is None or item.color == "NA":
383
        t_line_item.color = ""
384
    else:
385
        t_line_item.color = item.color
386
    t_line_item.model_name = item.modelName
387
    t_line_item.extra_info = item.featureDescription
388
    t_line_item.item_id = item.id
389
    t_line_item.quantity = quantity
1983 varun.gupt 390
 
17812 amit.gupta 391
    t_line_item.unit_price = final_price
392
    t_line_item.total_price = final_price * quantity
393
 
394
    t_line_item.unit_weight = item.weight
395
    t_line_item.total_weight = item.weight if item.weight is None else item.weight * quantity
396
    if line.dealText is None:
397
        t_line_item.dealText = item.bestDealText
398
    elif line.dealText == '':
399
        t_line_item.dealText = None
400
    else:
401
        t_line_item.dealText = line.dealText
11915 amit.gupta 402
 
17812 amit.gupta 403
    if item.warrantyPeriod:
404
        #Computing Manufacturer Warranty expiry date
405
        today = datetime.date.today()
406
        expiry_year = today.year + int((today.month + item.warrantyPeriod) / 12)
407
        expiry_month = (today.month + item.warrantyPeriod) % 12
4312 rajveer 408
 
17812 amit.gupta 409
        try:
410
            expiry_date = datetime.datetime(expiry_year, expiry_month, today.day, 23, 59, 59, 999999)
411
        except ValueError:
4295 varun.gupt 412
            try:
17812 amit.gupta 413
                expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 1), 23, 59, 59, 999999)
4295 varun.gupt 414
            except ValueError:
4312 rajveer 415
                try:
17812 amit.gupta 416
                    expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 2), 23, 59, 59, 999999)
4312 rajveer 417
                except ValueError:
17812 amit.gupta 418
                    expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 3), 23, 59, 59, 999999)
4312 rajveer 419
 
17812 amit.gupta 420
        t_line_item.warrantry_expiry_timestamp = to_java_date(expiry_date)
4312 rajveer 421
 
17812 amit.gupta 422
    return t_line_item
576 chandransh 423
 
17812 amit.gupta 424
def validate_cart(cartId, sourceId, couponCode):
425
    inventory_client = CatalogClient().get_client()
426
    logistics_client = LogisticsClient().get_client()
427
    promotion_client = PromotionClient().get_client()
428
    retval = ""
429
    emival = ""
430
    # No need to validate duplicate items since there are only two ways
431
    # to add items to a cart and both of them check whether the item being
432
    # added is a duplicate of an already existing item.
433
    cart = Cart.get_by(id=cartId)
434
    cart_lines = cart.lines
435
    customer_pincode = None
436
    current_time = datetime.datetime.now()
437
    if cart.pickupStoreId :
438
        store = logistics_client.getPickupStore(cart.pickupStoreId)
439
        customer_pincode = store.pin
440
    if cart.address_id != None and customer_pincode == None:
441
        address = Address.get_by(id=cart.address_id)
442
        customer_pincode = address.pin
443
 
444
    user = User.get_by(active_cart_id = cartId)
13136 amit.gupta 445
 
17812 amit.gupta 446
    dealItems = []
447
    privateDealUser = PrivateDealUser.get_by(id=user.id)    
448
    if privateDealUser is not None and privateDealUser.isActive:
449
        itemIds = [cartLine.item_id for cartLine in cart.lines]
450
        deals = inventory_client.getAllActivePrivateDeals(itemIds, 0)
451
        dealItems = deals.keys()
452
 
453
    if not customer_pincode:
454
        default_address_id = user.default_address_id
455
        if default_address_id:
456
            address = Address.get_by(id = default_address_id)
457
            customer_pincode = address.pin
458
    if not customer_pincode:
459
        #FIXME should not be hard coded. May be we can pick from config server.
460
        customer_pincode = "110001"
461
    cart.total_price = 0
462
    for line in cart_lines:
463
        old_estimate = line.estimate
464
        item_id = line.item_id
465
        item = inventory_client.getItemForSource(item_id, sourceId)
466
 
467
        item_shipping_info = inventory_client.isActive(item_id) 
468
        if item_shipping_info.isActive:
469
            if item_shipping_info.isRisky and item_shipping_info.quantity < line.quantity:
470
                line.quantity = 1
471
                retval = "Try adding a smaller quantity of " + item.brand + " " + item.modelNumber + " (" + item.color + ")"
472
 
473
            if item_id in dealItems:
474
                line.actual_price = deals[item_id].dealPrice
475
                if deals[item_id].dealTextOption==0:
476
                    line.dealText = ''
477
                if deals[item_id].dealTextOption==2:
478
                    line.dealText =  deals[item_id].dealText
479
 
480
                if deals[item_id].dealFreebieOption==0:
481
                    line.freebieId = 0
482
                if deals[item_id].dealFreebieOption==2:
483
                    line.freebieId =  deals[item_id].dealFreebieItemId
484
 
485
            else:
486
                line.actual_price = item.sellingPrice 
487
                line.dealText = None
488
                line.freebieId = None
489
            cart.total_price = cart.total_price + (line.actual_price * line.quantity)
490
            try:
491
                item_delivery_estimate = logistics_client.getLogisticsEstimation(item_id, customer_pincode, DeliveryType.PREPAID).deliveryTime
492
            except LogisticsServiceException:
493
                item_delivery_estimate = -1
494
                #TODO Use the exception clause to set the retval appropriately
495
            except :
496
                item_delivery_estimate = -1
497
 
498
            if item_delivery_estimate !=-1:
499
                inv_client = InventoryClient().get_client()
500
                itemAvailability = None
17803 amit.gupta 501
                try:
17812 amit.gupta 502
                    itemAvailability = inv_client.getItemAvailabilityAtLocation(item_id, 1)
503
                except:
504
                    pass
505
 
506
                print 'itemAvailability billling Warehouse ', itemAvailability[2]
507
                if itemAvailability is not None:
508
                    billingWarehouse = None
12893 manish.sha 509
                    try:
17812 amit.gupta 510
                        billingWarehouse = inv_client.getWarehouse(itemAvailability[2])
12893 manish.sha 511
                    except:
512
                        pass
12904 manish.sha 513
 
17812 amit.gupta 514
                    print 'billingWarehouse Id Location ', billingWarehouse.stateId
515
                    if billingWarehouse is not None:
516
                        estimateVal = None
517
                        if not logistics_client.isAlive() :
518
                            logistics_client = LogisticsClient().get_client()
12893 manish.sha 519
                        try:
17812 amit.gupta 520
                            estimateVal = logistics_client.getFirstDeliveryEstimateForWhLocation(customer_pincode, billingWarehouse.stateId)
521
                            if estimateVal ==-1:
522
                                item_delivery_estimate =-1
12893 manish.sha 523
                        except:
524
                            pass
17812 amit.gupta 525
                        print 'estimateVal Value ', estimateVal
526
            if old_estimate != item_delivery_estimate:
527
                line.estimate = item_delivery_estimate
528
                cart.updated_on = current_time
529
        else:
530
            Discount.query.filter(Discount.line==line).delete()
531
            line.delete()
532
    if cart.checked_out_on is not None:
533
        if cart.updated_on > cart.checked_out_on:
534
            cart.checked_out_on = None
535
    session.commit()
1976 varun.gupt 536
 
17812 amit.gupta 537
    if cart.coupon_code is not None:
538
        try:
539
            updated_cart = promotion_client.applyCoupon(cart.coupon_code, cart.id)
540
            if updated_cart.message is not None:
541
                emival = updated_cart.message
542
        except PromotionException as ex:
543
            remove_coupon(cart.id)
544
            #retval = ex.message
545
    session.commit()
13136 amit.gupta 546
 
17812 amit.gupta 547
    cart = Cart.get_by(id=cartId)
548
    cart_lines = cart.lines
549
    map_lines = {}
13136 amit.gupta 550
 
17812 amit.gupta 551
    insurerFlag = False
552
    for line in cart_lines:
553
        if line.insurer > 0 or line.dataProtectionInsurer > 0:
554
            line_map = {}
555
            line_map['insurer'] = line.insurer
556
            line_map['dpinsurer'] = line.dataProtectionInsurer
557
            line_map['amount'] = line.discounted_price if line.discounted_price else line.actual_price
558
            line_map['quantity'] = line.quantity
559
            insurerFlag = True
560
            map_lines[line.item_id] = line_map
561
 
562
    if insurerFlag:
563
        map_lines = inventory_client.checkServices(map_lines)
564
        for line in cart_lines :
565
            if map_lines.has_key(line.item_id):
566
                line_map = map_lines[line.item_id]
567
                if line_map['insurer'] > 0:
568
                    if cart.discounted_price:
569
                        cart.discounted_price = cart.discounted_price + line_map['insureramount']
570
                    line.insurer = line_map['insurer']
571
                    line.insuranceAmount = line_map['insureramount']
572
                    cart.total_price = cart.total_price + line_map['insureramount']
573
                if line_map['dpinsurer'] > 0:
574
                    if cart.discounted_price:
575
                        cart.discounted_price = cart.discounted_price + line_map['dpinsureramount']
576
                    line.dataProtectionInsurer = line_map['dpinsurer']
577
                    line.dataProtectionAmount = line_map['dpinsureramount']
578
                    cart.total_price = cart.total_price + line_map['dpinsureramount']
579
                line.updated_on = datetime.datetime.now()
17803 amit.gupta 580
        cart.updated_on = datetime.datetime.now()
13142 amit.gupta 581
        session.commit()
17812 amit.gupta 582
    session.close()
583
    return [retval, emival]
584
 
585
def merge_cart(fromCartId, toCartId):
586
    fromCart = Cart.get_by(id=fromCartId)
587
    toCart = Cart.get_by(id=toCartId)
557 chandransh 588
 
17812 amit.gupta 589
    old_lines = fromCart.lines
590
    new_lines = toCart.lines
557 chandransh 591
 
17812 amit.gupta 592
    for line in old_lines:
593
        for discount in line.discounts:
594
            discount.delete()
595
    session.commit()
596
 
597
    for line in old_lines:
598
        flag = True
599
        for new_line in new_lines:
600
            if line.item_id == new_line.item_id:
601
                flag = False
602
 
603
        if flag:
604
            line.cart_id = toCartId
605
        else:
606
            line.delete()
5345 rajveer 607
 
17812 amit.gupta 608
    if toCart.coupon_code is None:
609
        toCart.coupon_code = fromCart.coupon_code
2019 varun.gupt 610
 
17812 amit.gupta 611
    toCart.updated_on = datetime.datetime.now()
612
    fromCart.expired_on = datetime.datetime.now()
613
    fromCart.cart_status = CartStatus.INACTIVE
614
    session.commit()
615
 
616
def check_out(cartId):
617
    if cartId is None:
618
        raise ShoppingCartException(101, "Cart id not specified")
619
    cart = Cart.get_by(id = cartId)
620
    if cart is None:
621
        raise ShoppingCartException(102, "The specified cart couldn't be found")
622
    cart.checked_out_on = datetime.datetime.now()
623
    session.commit()
624
    return True
625
 
626
def reset_cart(cartId, items):
627
    if cartId is None:
628
        raise ShoppingCartException(101, "Cart id not specified")
629
    for item_id, quantity in items.iteritems():
630
        line = Line.query.filter_by(cart_id=cartId, item_id=item_id).one()
631
        if line is not None:
632
            delete_discounts_for_line(line)
633
            line.discounted_price = None
634
            line.quantity = line.quantity - quantity
635
            if line.quantity == 0:
636
                line.delete()
637
    cart = Cart.get_by(id=cartId)
638
    cart.updated_on = datetime.datetime.now()
639
    cart.checked_out_on = None
1976 varun.gupt 640
 
17812 amit.gupta 641
    # Removing Coupon
642
    cart.total_price = None
643
    cart.discounted_price = None
644
    cart.coupon_code = None
645
 
646
    session.commit()
647
    return True
648
 
649
def get_carts_with_coupon_count(coupon_code):
650
    return Cart.query.filter_by(coupon_code = coupon_code).count()
651
 
652
def show_cod_option(cartId, sourceId, pincode):
653
    cart = Cart.get_by(id = cartId)
654
    cod_option = True
655
    logistics_client = LogisticsClient().get_client()
656
    if cart:
657
        if cart.coupon_code:
658
            promotion_client = PromotionClient().get_client()
659
            cod_option = promotion_client.isCodApplicable(to_t_cart(cart))
5351 varun.gupt 660
 
17812 amit.gupta 661
        if cod_option and cart.lines:
662
            for line in cart.lines:
663
                logistics_info = logistics_client.getLogisticsEstimation(line.item_id, pincode, DeliveryType.PREPAID)
664
                if not logistics_info.codAllowed:
665
                    cod_option = False
666
                    break
667
            if cart.total_price > 60000:# or cart.total_price <= 250:
668
                cod_option = False
669
    return cod_option
670
 
671
def get_products_added_to_cart(startDate, endDate):
672
    lines = session.query(Line.item_id).filter(Line.created_on > to_py_date(startDate)).filter(Line.created_on < to_py_date(endDate)).all()
673
    datas = []
674
    for line in lines:
675
        datas.append(line[0])
676
    return datas
677
 
678
def insure_item(itemId, cartId, toInsure, insurerType):
679
    cart = Cart.get_by(id = cartId)
680
    line = None
681
    for cartLine in cart.lines:
682
        if(cartLine.item_id == itemId):
683
            line = cartLine
684
            break
11655 amit.gupta 685
 
17812 amit.gupta 686
    if not line:
687
        print("Error : No line found for cartId : " + cartId + " and itemId : " + itemId)
688
        return False
11655 amit.gupta 689
 
17812 amit.gupta 690
    try:
691
        if toInsure:
692
            csc = CatalogClient().get_client()
693
            item = csc.getItem(itemId)
694
            insurerId = csc.getPrefferedInsurerForItem(itemId,insurerType)
695
            insuranceAmount = csc.getInsuranceAmount(itemId, line.discounted_price if line.discounted_price else line.actual_price, insurerId, line.quantity)
696
            if InsurerType._VALUES_TO_NAMES.get(insurerType)=='DEVICE':
9299 kshitij.so 697
                if cart.discounted_price:
17812 amit.gupta 698
                    cart.discounted_price = cart.discounted_price - line.insuranceAmount + insuranceAmount
699
                line.insurer = insurerId
700
                line.insuranceAmount = insuranceAmount
701
            if InsurerType._VALUES_TO_NAMES.get(insurerType)=='DATA':
702
                if cart.discounted_price:
703
                    cart.discounted_price = cart.discounted_price - line.dataProtectionAmount + insuranceAmount
704
                line.dataProtectionInsurer = insurerId
705
                line.dataProtectionAmount = insuranceAmount
706
            cart.total_price = cart.total_price + insuranceAmount
707
        else:
708
            if InsurerType._VALUES_TO_NAMES.get(insurerType)=='DEVICE':
709
                cart.total_price = cart.total_price - line.insuranceAmount
710
                if cart.discounted_price:
711
                    cart.discounted_price = cart.discounted_price - line.insuranceAmount
712
                line.insurer = 0
713
                line.insuranceAmount = 0
714
            if InsurerType._VALUES_TO_NAMES.get(insurerType)=='DATA':
715
                cart.total_price = cart.total_price - line.dataProtectionAmount
716
                if cart.discounted_price:
717
                    cart.discounted_price = cart.discounted_price - line.dataProtectionAmount
718
                line.dataProtectionInsurer = 0
719
                line.dataProtectionAmount = 0
720
        line.updated_on = datetime.datetime.now()
721
        cart.updated_on = datetime.datetime.now()
722
        session.commit()
723
    except:
724
        print("Error : Unable to insure")
725
        print("insurerId : " + str(insurerId) + " ItemId : " + str(itemId) + " CartId : " + str(cartId))
726
        return False
6903 anupam.sin 727
 
17812 amit.gupta 728
    return True
729
 
730
def cancel_insurance(cartId):
731
    try:
732
        cart = Cart.get_by(id = cartId)
733
        for cartLine in cart.lines:
734
            cart.total_price = cart.total_price - cartLine.insuranceAmount
735
            if cart.discounted_price:
736
                cart.discounted_price = cart.discounted_price - cartLine.insuranceAmount
737
            cartLine.insurer = 0
738
            cartLine.insuranceAmount = 0
739
            cartLine.updated_on = datetime.datetime.now()
740
        cart.updated_on = datetime.datetime.now()
741
        session.commit()
742
    except:
743
        print("Error : Unable to cancel insurance for cartId :" + str(cartId))
744
        return False
6903 anupam.sin 745
 
17812 amit.gupta 746
    return True
747
 
748
def store_insurance_specific_details(addressId, dob, guardianName):
749
    try:
750
        insuranceDetails = InsuranceDetails.get_by(addressId = addressId);
751
        if insuranceDetails is None :
752
            insuranceDetails = InsuranceDetails()
753
        insuranceDetails.addressId = addressId
754
        insuranceDetails.dob = dob
755
        insuranceDetails.guardianName = guardianName
756
        session.commit()
757
    except:
758
        print("Error : Unable to store insurance details for addressId : " + str(addressId))
759
        return False
760
    return True
761
 
762
def is_insurance_detail_present(addressId):
763
    try:
764
        insuranceDetails = InsuranceDetails.get_by(addressId = addressId);
765
        if insuranceDetails is None :
6903 anupam.sin 766
            return False
17812 amit.gupta 767
    except:
768
        print("Error : Unable to get insurance details for addressId : " + str(addressId))
769
        return False
770
    return True
771
 
772
 
773
def add_items_to_cart(cartId, itemQty, couponCode=None):
774
    try: 
775
        found_cart = Cart.get_by(id=cartId)
776
        itemQtyMap = {}
777
        current_time = datetime.datetime.now()
778
        for itemqty in itemQty:
779
            itemQtyMap[itemqty.itemId] = itemqty.qty 
780
 
781
        if found_cart.lines:
782
            for line in found_cart.lines:
783
                if itemQtyMap.has_key(line.item_id):
784
                    line.delete()
785
        for itemId,qty in itemQtyMap.iteritems():
786
            #This condition will ensure that cart is only persisted with non-zero quantities.
787
            if qty==0:
788
                continue
789
            line = Line()
790
            line.cart = found_cart
791
            line.item_id = itemId
792
            line.quantity = qty
793
            line.created_on = current_time
794
            line.updated_on = current_time
795
            line.line_status = LineStatus.LINE_ACTIVE
796
            line.insurer = 0
797
            line.insuranceAmount = 0
798
        if couponCode:
799
            found_cart.coupon_code = couponCode
800
        else:
801
            found_cart.coupon_code = None
802
        session.commit()
17782 amit.gupta 803
        return True
17812 amit.gupta 804
    except:
805
        traceback.print_exc()
806
        return False
807
 
17782 amit.gupta 808
 
17812 amit.gupta 809
def valiate_cart_new(cartId, customer_pincode, sourceId):
17782 amit.gupta 810
 
17812 amit.gupta 811
    inventory_client = CatalogClient().get_client()
812
    logistics_client = LogisticsClient().get_client()
813
    promotion_client = PromotionClient().get_client()
814
    # No need to validate duplicate items since there are only two ways
815
    # to add items to a cart and both of them check whether the item being
816
    # added is a duplicate of an already existing item.
817
    cart = Cart.get_by(id=cartId)
818
    cart_lines = cart.lines
819
    current_time = datetime.datetime.now()
820
 
821
    user = User.get_by(active_cart_id = cartId)
822
    responseMap = {}
823
    totalQty = 0
824
    totalAmount = 0 
825
    shippingCharges=0
826
    cartMessages=[]
827
    cartItems = []
828
    dealItems = []
17782 amit.gupta 829
 
17812 amit.gupta 830
    responseMap['shippingCharges']= shippingCharges
831
    responseMap['cartMessages']= cartMessages
832
    responseMap['cartItems']= cartItems
833
    responseMap['pincode']= customer_pincode
834
 
835
    privateDealUser = PrivateDealUser.get_by(id=user.id)    
836
    itemIds = [cartLine.item_id for cartLine in cart.lines]
837
    if privateDealUser is not None and privateDealUser.isActive:
838
        deals = inventory_client.getAllActivePrivateDeals(itemIds, 0)
839
        dealItems = deals.keys()
840
 
841
    cart.total_price = 0
842
    itemsMap = inventory_client.getItems(itemIds)
17789 amit.gupta 843
 
17812 amit.gupta 844
    cartMessageChanged = 0
845
    cartMessageOOS = 0
846
    cartMessageUndeliverable = 0
17789 amit.gupta 847
 
17812 amit.gupta 848
    for line in cart_lines:
17865 amit.gupta 849
        itemQuantityChanged=False
17812 amit.gupta 850
        cartItem={}
17782 amit.gupta 851
 
17812 amit.gupta 852
        old_estimate = line.estimate
853
        item_id = line.item_id
854
        item = itemsMap.get(item_id)
18375 amit.gupta 855
        if item.status==0:
856
            Discount.query.filter(Discount.line==line).delete()
857
            line.delete()
858
            continue
17812 amit.gupta 859
        cartItem['itemId']=line.item_id
860
        cartItem['quantity']=0
17813 amit.gupta 861
        cartItem['cartItemMessages']=[]
862
        cartItemMessages = cartItem['cartItemMessages']
17812 amit.gupta 863
        cartItem['color'] = item.color
864
        cartItem['catalogItemId'] = item.catalogItemId
18006 manish.sha 865
        cartItem['packQuantity'] = item.packQuantity
17782 amit.gupta 866
 
17903 amit.gupta 867
        if item_id in dealItems:
868
            line.actual_price = deals[item_id].dealPrice
869
            if deals[item_id].dealTextOption==0:
870
                line.dealText = ''
871
            if deals[item_id].dealTextOption==2:
872
                line.dealText = deals[item_id].dealText
873
 
874
            if deals[item_id].dealFreebieOption==0:
875
                line.freebieId = 0
876
            if deals[item_id].dealFreebieOption==2:
877
                line.freebieId =  deals[item_id].dealFreebieItemId
878
            cartItem['dealText'] = line.dealText
879
        else:
880
            line.actual_price = item.sellingPrice
881
            if item.bestDealText:
882
                cartItem['dealText'] = item.bestDealText
883
            line.dealText = None
884
            line.freebieId = None
885
        cartItem['sellingPrice'] = line.actual_price
886
 
17812 amit.gupta 887
        item_shipping_info = inventory_client.isActive(item_id) 
888
        if item_shipping_info.isActive:
889
            if item_shipping_info.isRisky and item_shipping_info.quantity < line.quantity:
890
                line.quantity = item_shipping_info.quantity
17865 amit.gupta 891
                itemQuantityChanged=True
17903 amit.gupta 892
            cartItem['quantity'] = line.quantity
17812 amit.gupta 893
            cartItem['maxQuantity'] = min(item_shipping_info.quantity, 20)
894
            cart.total_price = cart.total_price + (line.actual_price * line.quantity)
895
            try:
896
                item_delivery_estimate = logistics_client.getLogisticsEstimation(item_id, customer_pincode, DeliveryType.PREPAID).deliveryTime
897
            except LogisticsServiceException:
898
                item_delivery_estimate = -1
899
                #TODO Use the exception clause to set the retval appropriately
900
            except :
901
                item_delivery_estimate = -1
17782 amit.gupta 902
 
17812 amit.gupta 903
            if item_delivery_estimate !=-1:
904
                inv_client = InventoryClient().get_client()
905
                itemAvailability = None
906
                try:
907
                    itemAvailability = inv_client.getItemAvailabilityAtLocation(item_id, 1)
908
                except:
909
                    pass
17803 amit.gupta 910
 
17812 amit.gupta 911
                print 'itemAvailability billling Warehouse ', itemAvailability[2]
912
                if itemAvailability is not None:
913
                    billingWarehouse = None
17782 amit.gupta 914
                    try:
17812 amit.gupta 915
                        billingWarehouse = inv_client.getWarehouse(itemAvailability[2])
17782 amit.gupta 916
                    except:
917
                        pass
918
 
17812 amit.gupta 919
                    print 'billingWarehouse Id Location ', billingWarehouse.stateId
920
                    if billingWarehouse is not None:
921
                        estimateVal = None
922
                        if not logistics_client.isAlive() :
923
                            logistics_client = LogisticsClient().get_client()
17782 amit.gupta 924
                        try:
17812 amit.gupta 925
                            estimateVal = logistics_client.getFirstDeliveryEstimateForWhLocation(customer_pincode, billingWarehouse.stateId)
926
                            if estimateVal ==-1:
927
                                item_delivery_estimate =-1
17782 amit.gupta 928
                        except:
929
                            pass
17812 amit.gupta 930
                        print 'estimateVal Value ', estimateVal
931
            cartItem['estimate'] = item_delivery_estimate
932
            if item_delivery_estimate == -1:
17782 amit.gupta 933
                cartItem['quantity'] = 0
17812 amit.gupta 934
                cartMessageUndeliverable += 1
17836 amit.gupta 935
                cartItemMessages.append({"type":"danger", "messageText":"Undeliverable"})
17865 amit.gupta 936
            elif itemQuantityChanged:
937
                cartMessageChanged += 1
938
                cartItemMessages.append({"type":"danger", "messageText":"Only " + str(item_shipping_info.quantity) + " available"})
17812 amit.gupta 939
            if old_estimate != item_delivery_estimate:
940
                line.estimate = item_delivery_estimate
941
                cart.updated_on = current_time
17903 amit.gupta 942
            totalAmount += line.actual_price * cartItem['quantity']
17812 amit.gupta 943
        else:
944
            cartItem['quantity'] = 0
945
            cartMessageOOS += 1
946
            cartItemMessages.append({"type":"danger", "messageText":"Out of Stock"})
947
            Discount.query.filter(Discount.line==line).delete()
948
            line.delete()
949
        totalQty += cartItem['quantity']
950
        if cartItemMessages:
951
            cartItems.insert(0, cartItem)
952
        else:
953
            cartItems.append(cartItem)
954
    if cart.checked_out_on is not None:
955
        if cart.updated_on > cart.checked_out_on:
956
            cart.checked_out_on = None
957
    session.commit()
958
 
959
    if cart.coupon_code is not None:
960
        try:
961
            updated_cart = promotion_client.applyCoupon(cart.coupon_code, cart.id)
962
            if updated_cart.message is not None:
963
                emival = updated_cart.message
964
        except PromotionException as ex:
965
            remove_coupon(cart.id)
966
            #retval = ex.message
967
    session.commit()
968
 
969
    cart = Cart.get_by(id=cartId)
970
    cart_lines = cart.lines
971
    insurerFlag = False
972
    for line in cart_lines:
973
        if line.insurer > 0 or line.dataProtectionInsurer > 0:
974
            line.insurer = 0
975
            line.insuranceAmount = 0 
976
            line.dataProtectionInsurer = 0
977
            line.dataProtectionAmount = 0
978
            insurerFlag = True
17782 amit.gupta 979
 
17812 amit.gupta 980
    if insurerFlag:
981
        cart.updated_on = datetime.datetime.now()
17782 amit.gupta 982
        session.commit()
17812 amit.gupta 983
    session.close()
984
    responseMap['totalQty']= totalQty
985
    responseMap['totalAmount']= totalAmount
17901 amit.gupta 986
    if totalAmount > 0 and totalAmount < 500:
17812 amit.gupta 987
        shippingCharges = 100
988
    elif totalAmount < 1000:
989
        shippingCharges = 50
990
    responseMap['shippingCharge']=shippingCharges
991
    responseMap['cartMessageChanged'] = cartMessageChanged
992
    responseMap['cartMessageOOS'] = cartMessageOOS
993
    responseMap['cartMessageUndeliverable'] = cartMessageUndeliverable
994
    return json.dumps(responseMap)
995
 
996
 
997
def validate_cart_plus(cart_id, source_id, couponCode):
998
    try:
999
        cart_messages = validate_cart(cart_id, source_id, couponCode)
1000
        found_cart = Cart.get_by(id=cart_id)
1001
        pincode = "110001"
1002
        default_address_id = User.get_by(active_cart_id = cart_id).default_address_id
11598 amit.gupta 1003
 
17812 amit.gupta 1004
        default_address = None
1005
        if found_cart.address_id is not None and found_cart.address_id > 0:
1006
            pincode = Address.get_by(id=found_cart.address_id).pin
1007
        elif default_address_id is not None:
1008
            default_address = Address.get_by(id = default_address_id) 
1009
            pincode = default_address.pin
11592 amit.gupta 1010
 
17812 amit.gupta 1011
        needInuranceInfo = False
1012
        if default_address_id is not None:
1013
            for line in found_cart.lines:
1014
                if line.insurer > 0:
1015
                    needInuranceInfo = not is_insurance_detail_present(default_address_id)
1016
                    break
1017
        cartPlus = CartPlus()
1018
        cartPlus.cart = to_t_cart(found_cart)
1019
        cartPlus.pinCode = pincode
1020
        cartPlus.validateCartMessages = cart_messages
1021
        cartPlus.needInsuranceInfo = needInuranceInfo
1022
        return cartPlus
1023
    finally:
1024
        close_session()
1025
 
1026
def close_session():
1027
    if session.is_active:
1028
        print "session is active. closing it."
1029
        session.close()