Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
557 chandransh 1
'''
2
Created on 10-May-2010
3
 
4
@author: ashish
5
'''
6
from elixir import *
3554 varun.gupt 7
from shop2020.model.v1.user.impl.Dataservice import Cart, Line, Address, User, Discount
2026 varun.gupt 8
from shop2020.thriftpy.model.v1.user.ttypes import CartStatus, LineStatus, ShoppingCartException,\
9
    PromotionException
557 chandransh 10
import datetime
576 chandransh 11
from shop2020.utils.Utils import to_py_date, to_java_date
557 chandransh 12
 
576 chandransh 13
from shop2020.thriftpy.model.v1.order.ttypes import Transaction as TTransaction,\
685 chandransh 14
    TransactionStatus as TTransactionStatus, Order as TOrder, LineItem as TLineItem, OrderStatus 
557 chandransh 15
 
576 chandransh 16
from shop2020.thriftpy.model.v1.catalog.ttypes import Item as TItem
844 chandransh 17
from shop2020.thriftpy.logistics.ttypes import LogisticsInfo as TLogisticsInfo,\
4642 mandeep.dh 18
    LogisticsServiceException, DeliveryType
576 chandransh 19
 
20
from shop2020.clients.TransactionClient import TransactionClient
3133 rajveer 21
from shop2020.clients.CatalogClient import CatalogClient
576 chandransh 22
from shop2020.clients.LogisticsClient import LogisticsClient
23
from shop2020.model.v1 import user
1976 varun.gupt 24
from shop2020.clients.PromotionClient import PromotionClient
2026 varun.gupt 25
from shop2020.model.v1.user.impl import UserDataAccessors
576 chandransh 26
 
557 chandransh 27
def get_cart(user_id):
28
    query = Cart.query.filter_by(user_id=user_id)      
29
    query = query.filter_by(cart_status = CartStatus.ACTIVE)
30
    try:
31
        cart = query.one()
32
        session.commit()
33
    except:
34
        return None
35
#        raise ShoppingCartException(101, "Cart does not exist")
36
    return cart
37
 
38
def get_cart_by_id(id):
39
    cart = Cart.get_by(id=id)
40
    return cart
41
 
42
def create_cart(user_id):
43
    cart = get_cart(user_id)
44
    if not cart: 
45
        cart = Cart()
46
        cart.user_id = user_id
47
        cart.created_on = datetime.datetime.now()
48
        cart.updated_on = datetime.datetime.now()
49
        cart.cart_status = CartStatus.ACTIVE
50
        session.commit()
51
    return cart
52
 
53
def get_cart_by_user_id_and_status(user_id, status):
54
    query = Cart.query.filter_by(user_id=user_id)
55
    if status:
56
        query = query.filter_by(cart_status=status)
57
    carts = query.all()
58
    return carts
59
 
60
def get_carts_by_status(status):
61
    return Cart.query.filter_by(cart_status=status).all()
62
 
63
def get_carts_between(start_time, end_time, status):
64
    init_time = to_py_date(start_time)
65
    finish_time = to_py_date(end_time)
66
 
67
    query = Cart.query
68
    if status:
69
        query = query.filter(Cart.cart_status==status)
70
    if init_time:
71
        query = query.filter(Cart.created_on >= init_time)
72
    if finish_time:
73
        query = query.filter(Cart.created_on <= finish_time)
74
 
75
    carts = query.all()
76
    return carts
77
 
643 chandransh 78
def get_line(item_id, cart_id, status, single):
557 chandransh 79
    #get cart first 
80
    try:
81
        found_cart = Cart.get_by(id=cart_id)
82
    except:
83
        raise ShoppingCartException(101, "cart not found ")
643 chandransh 84
    query = Line.query.filter_by(cart = found_cart, item_id = item_id)
557 chandransh 85
 
86
    if status:
87
        query = query.filter_by(line_status = status)
88
    else:
89
        query = query.filter_by(line_status = LineStatus.LINE_ACTIVE)
90
    try:
91
        if single:
92
            return query.one()
93
        else:
94
            return query.all()
95
    except:
96
        return None
97
 
98
def change_cart_status(cart_id, status):
99
    cart = get_cart_by_id(id)
100
    if not cart:
101
        raise ShoppingCartException(101, "no cart attached to this id")
102
    if not status:
103
        raise ShoppingCartException(101, "invalid status")
690 chandransh 104
    cart.cart_status = status
557 chandransh 105
    session.commit()
106
 
3557 rajveer 107
def add_item_to_cart(cart_id, item_id, quantity, sourceId):
557 chandransh 108
    if not item_id:
109
        raise ShoppingCartException(101, "item_id cannot be null")
110
 
111
    if not quantity:
112
        raise ShoppingCartException(101, "quantity cannot be null")    
643 chandransh 113
 
2983 chandransh 114
    cart = Cart.get_by(id = cart_id)    
557 chandransh 115
    if not cart:
116
        raise ShoppingCartException(101, "no cart attached to this id")
2983 chandransh 117
    retval = ""
3133 rajveer 118
    inventory_client = CatalogClient().get_client()
3557 rajveer 119
    item = inventory_client.getItemForSource(item_id, sourceId)
2983 chandransh 120
    item_shipping_info = inventory_client.isActive(item_id)
121
    if not item_shipping_info.isActive:
2035 rajveer 122
        return inventory_client.getItemStatusDescription(item_id)
557 chandransh 123
 
643 chandransh 124
    current_time = datetime.datetime.now()
125
    cart.updated_on = current_time
126
    line = get_line(item_id, cart_id, None,True)
127
    if line:
128
        #change the quantity only
129
        line.quantity = quantity
685 chandransh 130
        line.updated_on = current_time
643 chandransh 131
    else:
132
        line = Line()
133
        line.cart = cart
134
        line.item_id = item_id
135
        line.quantity = quantity
136
        line.created_on = current_time
137
        line.updated_on = current_time
3557 rajveer 138
        line.actual_price = item.sellingPrice
643 chandransh 139
        line.line_status = LineStatus.LINE_ACTIVE
557 chandransh 140
    session.commit()
2983 chandransh 141
    return retval
557 chandransh 142
 
143
def delete_item_from_cart(cart_id, item_id):
144
    if not item_id:
145
        raise ShoppingCartException(101, "item_id cannot be null")
685 chandransh 146
    cart = Cart.get_by(id = cart_id)
147
    if not cart:
148
        raise ShoppingCartException(101, "no cart attached to this id")
643 chandransh 149
    item = get_line(item_id, cart_id, None, True)
3554 varun.gupt 150
    count_deleted_discounts = delete_discounts_for_line(item)
557 chandransh 151
    item.delete()
685 chandransh 152
    current_time = datetime.datetime.now()
153
    cart.updated_on = current_time
557 chandransh 154
    session.commit()
155
 
3554 varun.gupt 156
def delete_discounts_for_line(item_line):
157
    count_deleted = Discount.query.filter_by(line = item_line).delete()
158
    session.commit()
159
    return count_deleted
160
 
161
def delete_discounts_from_cart(cart_id, cart = None):
162
    if cart is None:
163
        if cart_id is None:
164
            raise ShoppingCartException(101, 'cart_id and cart, both cannot be null')
165
        else:
166
            cart = Cart.get_by(id = cart_id)
167
 
168
    if cart.lines:
169
        for line in cart.lines:
170
            delete_discounts_for_line(line)
171
 
172
def save_discounts(discounts):
173
    if not discounts:
174
        raise ShoppingCartException(101, 'discounts be null')
175
 
176
    if len(discounts) > 0:
177
        cart = Cart.get_by(id = discounts[0].cart_id)
178
 
179
        for t_discount in discounts:
180
            line = Line.query.filter_by(cart = cart, item_id = t_discount.item_id).first()
181
            if line is not None:
182
                discount = Discount()
183
                discount.line = line
184
                discount.discount = t_discount.discount
185
                discount.quantity = t_discount.quantity
186
                session.commit()
187
 
557 chandransh 188
def change_item_status(cart_id, item_id, status):
189
    if not status:
190
        raise ShoppingCartException(101, "Status cannot be made null")
685 chandransh 191
    line = get_line(item_id, cart_id, None, True)
192
    if line:
193
        line.line_status = status
194
        current_time = datetime.datetime.now()
195
        line.updated_on = current_time
196
        line.cart.updated_on = current_time
557 chandransh 197
        session.commit()
198
    else:
685 chandransh 199
        raise ShoppingCartException(101, "Unable to probe the line you desired")
557 chandransh 200
 
201
def add_address_to_cart(cart_id, address_id):
202
    if not cart_id:
203
        raise ShoppingCartException(101, "cart id cannot be made null")
204
 
205
    if not address_id:
206
        raise ShoppingCartException(101, "address id cannot be made null")
207
 
208
    cart = get_cart_by_id(cart_id)
209
    if not cart:
210
        raise ShoppingCartException(101, "no cart for this id")
576 chandransh 211
 
212
    address = Address.get_by(id=address_id)
213
    if not address:
214
        raise ShoppingCartException(101, "No address for this id")
215
 
557 chandransh 216
    cart.address_id = address_id
685 chandransh 217
    current_time = datetime.datetime.now()
716 rajveer 218
    #cart.updated_on = current_time
557 chandransh 219
    session.commit()
220
 
1976 varun.gupt 221
def apply_coupon_to_cart(cart_id, coupon_code, total_price, discounted_price):
222
    cart = get_cart_by_id(cart_id)
223
    if not cart:
224
        raise ShoppingCartException(101, "no cart attached to this id")
225
    cart.total_price = total_price
226
    cart.discounted_price = discounted_price
227
    cart.coupon_code = coupon_code
228
    session.commit()
229
 
230
def remove_coupon(cart_id):
231
    cart = get_cart_by_id(cart_id)
232
    if not cart:
233
        raise ShoppingCartException(101, "no cart attached to this id")
2261 varun.gupt 234
 
235
    #Resetting discounted price of each line in cart to Null
236
    for line in cart.lines:
237
        line.discounted_price = None
238
 
3619 chandransh 239
    delete_discounts_from_cart(cart.id, cart=cart)
1976 varun.gupt 240
    cart.discounted_price = None
241
    cart.coupon_code = None
242
    session.commit()
243
 
3858 vikas 244
def commit_cart(cart_id, sessionSource, sessionTime, firstSource, firstSourceTime):   
690 chandransh 245
    cart = get_cart_by_id(cart_id)   
557 chandransh 246
    #now we have a cart. Need to create a transaction with it
576 chandransh 247
    txn = TTransaction()
248
    txn.shoppingCartid = cart_id
249
    txn.customer_id = cart.user_id
250
    txn.createdOn = to_java_date(datetime.datetime.now())
251
    txn.transactionStatus = TTransactionStatus.INIT
252
    txn.statusDescription = "New Order"
2219 varun.gupt 253
    txn.coupon_code = cart.coupon_code
2815 vikas 254
    txn.sessionSource = sessionSource
255
    txn.sessionStartTime = sessionTime
3858 vikas 256
    txn.firstSource = firstSource
257
    txn.firstSourceTime = firstSourceTime
557 chandransh 258
 
576 chandransh 259
    txn.orders = create_orders(cart)
260
 
261
    transaction_client = TransactionClient().get_client()
262
    txn_id = transaction_client.createTransaction(txn)
263
    session.commit()
264
 
685 chandransh 265
    #new_cart = create_cart(cart.user_id)
266
    #user = User.get_by(id=cart.user_id)
267
    #user.active_cart_id = new_cart.id
268
    #session.commit()
576 chandransh 269
    return txn_id
270
 
271
def create_orders(cart):
557 chandransh 272
    cart_lines = cart.lines
576 chandransh 273
    orders = []
274
 
557 chandransh 275
    for line in cart_lines:
576 chandransh 276
        if line.line_status == LineStatus.LINE_ACTIVE:
3554 varun.gupt 277
            quantity_remaining_for_order = line.quantity
278
 
279
            for discount in line.discounts:
280
                i = 0
281
                while i < discount.quantity:
282
                    t_line_item = create_line_item(line.item_id, line.actual_price - discount.discount)
283
                    t_order = create_order(cart.user_id, cart.address_id, t_line_item)
284
                    orders.append(t_order)
285
                    i += 1
286
                quantity_remaining_for_order -= discount.quantity
287
 
576 chandransh 288
            i = 0
3554 varun.gupt 289
            while i < quantity_remaining_for_order:
290
                t_line_item = create_line_item(line.item_id, line.actual_price)
576 chandransh 291
                t_order = create_order(cart.user_id, cart.address_id, t_line_item)
292
                orders.append(t_order)
293
                i += 1
294
    return orders
295
 
296
def create_order(user_id, address_id, t_line_item):
297
    user = User.get_by(id=user_id)
298
    address = Address.get_by(id=address_id)
299
    t_order = TOrder()
557 chandransh 300
 
576 chandransh 301
    t_order.customer_id = user.id
302
    t_order.customer_email = user.email
303
 
910 rajveer 304
    t_order.customer_name = address.name
576 chandransh 305
    t_order.customer_pincode = address.pin
738 chandransh 306
    t_order.customer_address1 = address.line_1
307
    t_order.customer_address2 = address.line_2
669 chandransh 308
    t_order.customer_city = address.city
309
    t_order.customer_state = address.state
576 chandransh 310
    t_order.customer_mobilenumber = address.phone
311
 
312
    t_order.total_amount = t_line_item.total_price
1976 varun.gupt 313
 
576 chandransh 314
    t_order.total_weight = t_line_item.total_weight
315
    t_order.lineitems = [t_line_item]
316
 
690 chandransh 317
    t_order.status = OrderStatus.PAYMENT_PENDING
970 chandransh 318
    t_order.statusDescription = "Payment Pending"
576 chandransh 319
    t_order.created_timestamp = to_java_date(datetime.datetime.now())
320
 
321
    return t_order
322
 
3768 vikas 323
def create_line_item(item_id, final_price, quantity=1):
3133 rajveer 324
    inventory_client = CatalogClient().get_client()
636 rajveer 325
    item = inventory_client.getItem(item_id)
576 chandransh 326
    t_line_item = TLineItem()
963 chandransh 327
    t_line_item.productGroup = item.productGroup
328
    t_line_item.brand = item.brand
636 rajveer 329
    t_line_item.model_number = item.modelNumber
669 chandransh 330
    if item.color is None or item.color == "NA":
331
        t_line_item.color = ""
332
    else:
917 chandransh 333
        t_line_item.color = item.color
963 chandransh 334
    t_line_item.model_name = item.modelName
636 rajveer 335
    t_line_item.extra_info = item.featureDescription
702 chandransh 336
    t_line_item.item_id = item.id
3768 vikas 337
    t_line_item.quantity = quantity
1983 varun.gupt 338
 
3554 varun.gupt 339
    t_line_item.unit_price = final_price
3768 vikas 340
    t_line_item.total_price = final_price * quantity
1983 varun.gupt 341
 
636 rajveer 342
    t_line_item.unit_weight = item.weight
4172 rajveer 343
    t_line_item.total_weight = item.weight if item.weight is None else item.weight * quantity
344
    t_line_item.dealText = item.bestDealText
4295 varun.gupt 345
 
4312 rajveer 346
    if item.warrantyPeriod:
347
        #Computing Manufacturer Warranty expiry date
348
        today = datetime.date.today()
349
        expiry_year = today.year + int((today.month + item.warrantyPeriod) / 12)
350
        expiry_month = (today.month + item.warrantyPeriod) % 12
351
 
4295 varun.gupt 352
        try:
4312 rajveer 353
            expiry_date = datetime.datetime(expiry_year, expiry_month, today.day, 23, 59, 59, 999999)
4295 varun.gupt 354
        except ValueError:
355
            try:
4312 rajveer 356
                expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 1), 23, 59, 59, 999999)
4295 varun.gupt 357
            except ValueError:
4312 rajveer 358
                try:
359
                    expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 2), 23, 59, 59, 999999)
360
                except ValueError:
361
                    expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 3), 23, 59, 59, 999999)
362
 
363
        t_line_item.warrantry_expiry_timestamp = to_java_date(expiry_date)
364
 
576 chandransh 365
    return t_line_item
366
 
3557 rajveer 367
def validate_cart(cartId, sourceId):
3133 rajveer 368
    inventory_client = CatalogClient().get_client()
576 chandransh 369
    logistics_client = LogisticsClient().get_client()
1976 varun.gupt 370
    promotion_client = PromotionClient().get_client()
1466 ankur.sing 371
    retval = ""
557 chandransh 372
    # No need to validate duplicate items since there are only two ways
373
    # to add items to a cart and both of them check whether the item being
374
    # added is a duplicate of an already existing item.
563 chandransh 375
    cart = Cart.get_by(id=cartId)
376
    cart_lines = cart.lines
776 rajveer 377
    customer_pincode = None
690 chandransh 378
    current_time = datetime.datetime.now()
576 chandransh 379
    if cart.address_id:
380
        address = Address.get_by(id=cart.address_id)
381
        customer_pincode = address.pin
776 rajveer 382
    if not customer_pincode:
785 rajveer 383
        user = User.get_by(active_cart_id = cartId)
384
        default_address_id = user.default_address_id
776 rajveer 385
        if default_address_id:
386
            address = Address.get_by(id = default_address_id)
387
            customer_pincode = address.pin
388
    if not customer_pincode:
389
        #FIXME should not be hard coded. May be we can pick from config server.
390
        customer_pincode = "110001"
1976 varun.gupt 391
    cart.total_price = 0
563 chandransh 392
    for line in cart_lines:
612 chandransh 393
        old_estimate = line.estimate
636 rajveer 394
        item_id = line.item_id
3557 rajveer 395
        item = inventory_client.getItemForSource(item_id, sourceId)
2983 chandransh 396
        item_shipping_info = inventory_client.isActive(item_id) 
397
        if item_shipping_info.isActive:
398
            if item_shipping_info.isRisky and item_shipping_info.quantity < line.quantity:
399
                line.quantity = 1
400
                retval = "Try adding a smaller quantity of " + item.brand + " " + item.modelNumber + " (" + item.color + ")"
401
 
2139 chandransh 402
            line.actual_price = item.sellingPrice 
403
            cart.total_price = cart.total_price + (line.actual_price * line.quantity)
776 rajveer 404
            try:
4642 mandeep.dh 405
                item_delivery_estimate = logistics_client.getLogisticsEstimation(item_id, customer_pincode, DeliveryType.PREPAID).deliveryTime
844 chandransh 406
            except LogisticsServiceException:
407
                item_delivery_estimate = -1
408
                #TODO Use the exception clause to set the retval appropriately
409
            except :
410
                item_delivery_estimate = -1
776 rajveer 411
            if old_estimate != item_delivery_estimate:
412
                line.estimate = item_delivery_estimate
413
                cart.updated_on = current_time
1466 ankur.sing 414
                if old_estimate != None:
415
                    retval = "Delivery Estimates updated."
576 chandransh 416
        else:
563 chandransh 417
            line.delete()
1466 ankur.sing 418
            retval = "Some items have been removed from the cart."
716 rajveer 419
    if cart.checked_out_on is not None:
420
        if cart.updated_on > cart.checked_out_on:
844 chandransh 421
            cart.checked_out_on = None
1466 ankur.sing 422
            if retval == "":
423
                retval = "Your cart has been updated after the last checkout."
612 chandransh 424
    session.commit()
1976 varun.gupt 425
 
426
    if cart.coupon_code is not None:
2026 varun.gupt 427
        try:
428
            updated_cart = promotion_client.applyCoupon(cart.coupon_code, cart.id)
429
            for t_line in updated_cart.lines:
1976 varun.gupt 430
            #Find the line in the database which corresponds to this line
2026 varun.gupt 431
                line = Line.query.filter_by(cart = cart).filter_by(item_id = t_line.itemId).one()
1976 varun.gupt 432
            #Update its discounted price.
2026 varun.gupt 433
                line.discounted_price = t_line.discountedPrice
434
            cart.discounted_price = updated_cart.discountedPrice
435
            session.commit()
436
        except PromotionException as ex:
437
            remove_coupon(cart.id)
438
            retval = ex.message
563 chandransh 439
    return retval
576 chandransh 440
 
557 chandransh 441
def merge_cart(fromCartId, toCartId):
442
    fromCart = Cart.get_by(id=fromCartId)
443
    toCart = Cart.get_by(id=toCartId)
444
 
445
    old_lines = fromCart.lines
446
    new_lines = toCart.lines
447
 
448
    for line in old_lines:
449
        flag = True
450
        for new_line in new_lines:
451
            if line.item_id == new_line.item_id:
452
                flag = False
576 chandransh 453
        if flag:
3819 rajveer 454
            n_line = Line()
455
            n_line.item_id = line.item_id 
456
            n_line.quantity = line.quantity
457
            n_line.line_status = line.line_status
458
            n_line.estimate = line.estimate
459
            n_line.created_on = line.created_on
460
            n_line.updated_on = line.updated_on
461
            n_line.actual_price = line.actual_price
462
            toCart.lines.append(n_line)
557 chandransh 463
 
2019 varun.gupt 464
    if toCart.coupon_code is None:
465
        toCart.coupon_code = fromCart.coupon_code
466
 
467
    toCart.updated_on = datetime.datetime.now()
557 chandransh 468
    fromCart.expired_on = datetime.datetime.now()
469
    fromCart.cart_status = CartStatus.INACTIVE
643 chandransh 470
    session.commit()
691 chandransh 471
 
472
def check_out(cartId):
473
    if cartId is None:
474
        raise ShoppingCartException(101, "Cart id not specified")
716 rajveer 475
    cart = Cart.get_by(id = cartId)
691 chandransh 476
    if cart is None:
477
        raise ShoppingCartException(102, "The specified cart couldn't be found")
478
    cart.checked_out_on = datetime.datetime.now()
479
    session.commit()
480
    return True
481
 
482
def reset_cart(cartId, items):
483
    if cartId is None:
484
        raise ShoppingCartException(101, "Cart id not specified")
485
    for item_id, quantity in items.iteritems():
486
        line = Line.query.filter_by(cart_id=cartId, item_id=item_id).one()
487
        if line is not None:
3566 rajveer 488
            delete_discounts_for_line(line)
2261 varun.gupt 489
            line.discounted_price = None
691 chandransh 490
            line.quantity = line.quantity - quantity
491
            if line.quantity == 0:
492
                line.delete()
717 rajveer 493
    cart = Cart.get_by(id=cartId)
691 chandransh 494
    cart.updated_on = datetime.datetime.now()
1894 vikas 495
    cart.checked_out_on = None
1976 varun.gupt 496
 
497
    # Removing Coupon
498
    cart.total_price = None
499
    cart.discounted_price = None
500
    cart.coupon_code = None
501
 
691 chandransh 502
    session.commit()
766 rajveer 503
    return True
504
 
3386 varun.gupt 505
def get_carts_with_coupon_count(coupon_code):
506
    return Cart.query.filter_by(coupon_code = coupon_code).count()
4668 varun.gupt 507
 
508
def show_cod_option(cartId, sourceId, pincode):
509
    cart = Cart.get_by(id = cartId)
510
    cod_option = True
511
    COD_MIN_AMOUNT = 100
512
    COD_MAX_AMOUNT = 10000
513
    inventory_client = CatalogClient().get_client()
514
    logistics_client = LogisticsClient().get_client()
3386 varun.gupt 515
 
4668 varun.gupt 516
    if cart:
517
        if cart.coupon_code and cart.coupon_code.lower() == 'sh911':
518
            cod_option = False 
519
 
520
        elif cart.lines:
521
            for line in cart.lines:
522
                item = inventory_client.getItemForSource(line.item_id, sourceId)
523
 
524
                if item and (item.sellingPrice < COD_MIN_AMOUNT or item.sellingPrice > COD_MAX_AMOUNT):
525
                    cod_option = False
526
                    break
527
 
528
    if pincode and cod_option:
529
        cod_option = logistics_client.isCodAllowed(pincode)
530
 
531
    return cod_option
532
 
766 rajveer 533
def close_session():
534
    if session.is_active:
535
        print "session is active. closing it."
1621 rajveer 536
        session.close()