Rev 6355 | Rev 6528 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
'''Created on 10-May-2010@author: ashish'''from elixir import *from shop2020.model.v1.user.impl.Dataservice import Cart, Line, Address, User, Discountfrom shop2020.thriftpy.model.v1.user.ttypes import CartStatus, LineStatus, ShoppingCartException,\PromotionExceptionimport datetimefrom shop2020.utils.Utils import to_py_date, to_java_datefrom shop2020.thriftpy.model.v1.order.ttypes import Transaction as TTransaction,\TransactionStatus as TTransactionStatus, Order as TOrder, LineItem as TLineItem, OrderStatusfrom shop2020.thriftpy.logistics.ttypes import LogisticsServiceException, DeliveryTypefrom shop2020.clients.TransactionClient import TransactionClientfrom shop2020.clients.CatalogClient import CatalogClientfrom shop2020.clients.LogisticsClient import LogisticsClientfrom shop2020.model.v1 import userfrom shop2020.clients.PromotionClient import PromotionClientdef get_cart(userId):user = User.get_by(id=userId)return user.active_cartdef get_cart_by_id(id):cart = Cart.get_by(id=id)return cartdef create_cart():cart = Cart()cart.created_on = datetime.datetime.now()cart.updated_on = datetime.datetime.now()cart.cart_status = CartStatus.ACTIVEreturn cartdef get_carts_between(start_time, end_time, status):init_time = to_py_date(start_time)finish_time = to_py_date(end_time)query = Cart.queryif status:query = query.filter(Cart.cart_status==status)if init_time:query = query.filter(Cart.created_on >= init_time)if finish_time:query = query.filter(Cart.created_on <= finish_time)carts = query.all()return cartsdef get_line(item_id, cart_id, status, single):#get cart firsttry:found_cart = Cart.get_by(id=cart_id)except:raise ShoppingCartException(101, "cart not found ")query = Line.query.filter_by(cart = found_cart, item_id = item_id)if status:query = query.filter_by(line_status = status)else:query = query.filter_by(line_status = LineStatus.LINE_ACTIVE)try:if single:return query.one()else:return query.all()except:return Nonedef add_item_to_cart(cart_id, item_id, quantity, sourceId):if not item_id:raise ShoppingCartException(101, "item_id cannot be null")if not quantity:raise ShoppingCartException(101, "quantity cannot be null")cart = Cart.get_by(id = cart_id)if not cart:raise ShoppingCartException(101, "no cart attached to this id")retval = ""inventory_client = CatalogClient().get_client()item = inventory_client.getItemForSource(item_id, sourceId)item_shipping_info = inventory_client.isActive(item_id)if not item_shipping_info.isActive:return inventory_client.getItemStatusDescription(item_id)current_time = datetime.datetime.now()cart.updated_on = current_timeline = get_line(item_id, cart_id, None,True)if line:#change the quantity onlyline.quantity = quantityline.updated_on = current_timeelse:line = Line()line.cart = cartline.item_id = item_idline.quantity = quantityline.created_on = current_timeline.updated_on = current_timeline.actual_price = item.sellingPriceline.line_status = LineStatus.LINE_ACTIVEsession.commit()return retvaldef delete_item_from_cart(cart_id, item_id):if not item_id:raise ShoppingCartException(101, "item_id cannot be null")cart = Cart.get_by(id = cart_id)if not cart:raise ShoppingCartException(101, "no cart attached to this id")item = get_line(item_id, cart_id, None, True)count_deleted_discounts = delete_discounts_for_line(item)item.delete()current_time = datetime.datetime.now()cart.updated_on = current_timesession.commit()def delete_discounts_for_line(item_line):count_deleted = Discount.query.filter_by(line = item_line).delete()session.commit()return count_deleteddef delete_discounts_from_cart(cart_id, cart = None):if cart is None:if cart_id is None:raise ShoppingCartException(101, 'cart_id and cart, both cannot be null')else:cart = Cart.get_by(id = cart_id)if cart.lines:for line in cart.lines:delete_discounts_for_line(line)def save_discounts(discounts):if not discounts:raise ShoppingCartException(101, 'discounts be null')if len(discounts) > 0:cart = Cart.get_by(id = discounts[0].cart_id)for t_discount in discounts:line = Line.query.filter_by(cart = cart, item_id = t_discount.item_id).first()if line is not None:discount = Discount()discount.line = linediscount.discount = t_discount.discountdiscount.quantity = t_discount.quantitysession.commit()def add_address_to_cart(cart_id, address_id):if not cart_id:raise ShoppingCartException(101, "cart id cannot be made null")if not address_id:raise ShoppingCartException(101, "address id cannot be made null")cart = get_cart_by_id(cart_id)if not cart:raise ShoppingCartException(101, "no cart for this id")address = Address.get_by(id=address_id)if not address:raise ShoppingCartException(101, "No address for this id")cart.address_id = address_idcurrent_time = datetime.datetime.now()#cart.updated_on = current_timesession.commit()def add_store_to_cart(cartId, storeId):if not cartId:raise ShoppingCartException(101, "cart id cannot be made null")cart = get_cart_by_id(cartId)if not cart:raise ShoppingCartException(101, "no cart for this id")if storeId:cart.pickupStoreId = storeIdelse:cart.pickupStoreId = Nonesession.commit()def apply_coupon_to_cart(cart_id, coupon_code, total_price, discounted_price):cart = get_cart_by_id(cart_id)if not cart:raise ShoppingCartException(101, "no cart attached to this id")cart.total_price = total_pricecart.discounted_price = discounted_pricecart.coupon_code = coupon_codesession.commit()def remove_coupon(cart_id):cart = get_cart_by_id(cart_id)if not cart:raise ShoppingCartException(101, "no cart attached to this id")#Resetting discounted price of each line in cart to Nullfor line in cart.lines:line.discounted_price = Nonedelete_discounts_from_cart(cart.id, cart=cart)cart.discounted_price = Nonecart.coupon_code = Nonesession.commit()def commit_cart(cart_id, sessionSource, sessionTime, firstSource, firstSourceTime, userId, schemeId):cart = get_cart_by_id(cart_id)#now we have a cart. Need to create a transaction with ittxn = TTransaction()txn.shoppingCartid = cart_idtxn.customer_id = userIdtxn.createdOn = to_java_date(datetime.datetime.now())txn.transactionStatus = TTransactionStatus.INITtxn.statusDescription = "New Order"txn.coupon_code = cart.coupon_codetxn.sessionSource = sessionSourcetxn.sessionStartTime = sessionTimetxn.firstSource = firstSourcetxn.firstSourceTime = firstSourceTimetxn.emiSchemeId = schemeIdtxn.orders = create_orders(cart, userId)transaction_client = TransactionClient().get_client()txn_id = transaction_client.createTransaction(txn)session.commit()return txn_iddef create_orders(cart, userId):cart_lines = cart.linesorders = []isGv = Falseif cart.coupon_code:try:pc = PromotionClient().get_client()isGv = pc.isGiftVoucher(cart.coupon_code)except:isGv = Falsefor line in cart_lines:if line.line_status == LineStatus.LINE_ACTIVE:quantity_remaining_for_order = line.quantityfor discount in line.discounts:i = 0while i < discount.quantity:t_line_item = create_line_item(line.item_id, line.actual_price if isGv else (line.actual_price - discount.discount))t_order = create_order(userId, cart.address_id, t_line_item, cart.pickupStoreId, discount.discount if isGv else 0)orders.append(t_order)i += 1quantity_remaining_for_order -= discount.quantityi = 0while i < quantity_remaining_for_order:t_line_item = create_line_item(line.item_id, line.actual_price)t_order = create_order(userId, cart.address_id, t_line_item, cart.pickupStoreId, 0)orders.append(t_order)i += 1return ordersdef create_order(userId, address_id, t_line_item, pickupStoreId, gvAmount):user = User.get_by(id=userId)address = Address.get_by(id=address_id)t_order = TOrder()t_order.customer_id = user.idt_order.customer_email = user.emailt_order.customer_name = address.namet_order.customer_pincode = address.pint_order.customer_address1 = address.line_1t_order.customer_address2 = address.line_2t_order.customer_city = address.cityt_order.customer_state = address.statet_order.customer_mobilenumber = address.phonet_order.total_amount = t_line_item.total_pricet_order.gvAmount = gvAmountt_order.total_weight = t_line_item.total_weightt_order.lineitems = [t_line_item]t_order.status = OrderStatus.PAYMENT_PENDINGt_order.statusDescription = "Payment Pending"t_order.created_timestamp = to_java_date(datetime.datetime.now())t_order.pickupStoreId = pickupStoreIdreturn t_orderdef create_line_item(item_id, final_price, quantity=1):inventory_client = CatalogClient().get_client()item = inventory_client.getItem(item_id)t_line_item = TLineItem()t_line_item.productGroup = item.productGroupt_line_item.brand = item.brandt_line_item.model_number = item.modelNumberif item.color is None or item.color == "NA":t_line_item.color = ""else:t_line_item.color = item.colort_line_item.model_name = item.modelNamet_line_item.extra_info = item.featureDescriptiont_line_item.item_id = item.idt_line_item.quantity = quantityt_line_item.unit_price = final_pricet_line_item.total_price = final_price * quantityt_line_item.unit_weight = item.weightt_line_item.total_weight = item.weight if item.weight is None else item.weight * quantityt_line_item.dealText = item.bestDealTextif item.warrantyPeriod:#Computing Manufacturer Warranty expiry datetoday = datetime.date.today()expiry_year = today.year + int((today.month + item.warrantyPeriod) / 12)expiry_month = (today.month + item.warrantyPeriod) % 12try:expiry_date = datetime.datetime(expiry_year, expiry_month, today.day, 23, 59, 59, 999999)except ValueError:try:expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 1), 23, 59, 59, 999999)except ValueError:try:expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 2), 23, 59, 59, 999999)except ValueError:expiry_date = datetime.date(expiry_year, expiry_month, (today.day - 3), 23, 59, 59, 999999)t_line_item.warrantry_expiry_timestamp = to_java_date(expiry_date)return t_line_itemdef validate_cart(cartId, sourceId):inventory_client = CatalogClient().get_client()logistics_client = LogisticsClient().get_client()promotion_client = PromotionClient().get_client()retval = ""# No need to validate duplicate items since there are only two ways# to add items to a cart and both of them check whether the item being# added is a duplicate of an already existing item.cart = Cart.get_by(id=cartId)cart_lines = cart.linescustomer_pincode = Nonecurrent_time = datetime.datetime.now()if cart.pickupStoreId :store = logistics_client.getPickupStore(cart.pickupStoreId)customer_pincode = store.pinif cart.address_id != None and customer_pincode == None:address = Address.get_by(id=cart.address_id)customer_pincode = address.pinif not customer_pincode:user = User.get_by(active_cart_id = cartId)default_address_id = user.default_address_idif default_address_id:address = Address.get_by(id = default_address_id)customer_pincode = address.pinif not customer_pincode:#FIXME should not be hard coded. May be we can pick from config server.customer_pincode = "110001"cart.total_price = 0for line in cart_lines:old_estimate = line.estimateitem_id = line.item_iditem = inventory_client.getItemForSource(item_id, sourceId)item_shipping_info = inventory_client.isActive(item_id)if item_shipping_info.isActive:if item_shipping_info.isRisky and item_shipping_info.quantity < line.quantity:line.quantity = 1retval = "Try adding a smaller quantity of " + item.brand + " " + item.modelNumber + " (" + item.color + ")"line.actual_price = item.sellingPricecart.total_price = cart.total_price + (line.actual_price * line.quantity)try:item_delivery_estimate = logistics_client.getLogisticsEstimation(item_id, customer_pincode, DeliveryType.PREPAID).deliveryTimeexcept LogisticsServiceException:item_delivery_estimate = -1#TODO Use the exception clause to set the retval appropriatelyexcept :item_delivery_estimate = -1if old_estimate != item_delivery_estimate:line.estimate = item_delivery_estimatecart.updated_on = current_timeif old_estimate != None:retval = "Delivery Estimates updated."else:line.delete()retval = "Some items have been removed from the cart."if cart.checked_out_on is not None:if cart.updated_on > cart.checked_out_on:cart.checked_out_on = Noneif retval == "":retval = "Your cart has been updated after the last checkout."session.commit()if cart.coupon_code is not None:try:updated_cart = promotion_client.applyCoupon(cart.coupon_code, cart.id)for t_line in updated_cart.lines:#Find the line in the database which corresponds to this lineline = Line.query.filter_by(cart = cart).filter_by(item_id = t_line.itemId).one()#Update its discounted price.line.discounted_price = t_line.discountedPricecart.discounted_price = updated_cart.discountedPricesession.commit()except PromotionException as ex:remove_coupon(cart.id)retval = ex.messagereturn retvaldef merge_cart(fromCartId, toCartId):fromCart = Cart.get_by(id=fromCartId)toCart = Cart.get_by(id=toCartId)old_lines = fromCart.linesnew_lines = toCart.linesfor line in old_lines:for discount in line.discounts:discount.delete()session.commit()for line in old_lines:flag = Truefor new_line in new_lines:if line.item_id == new_line.item_id:flag = Falseif flag:line.cart_id = toCartIdelse:line.delete()if toCart.coupon_code is None:toCart.coupon_code = fromCart.coupon_codetoCart.updated_on = datetime.datetime.now()fromCart.expired_on = datetime.datetime.now()fromCart.cart_status = CartStatus.INACTIVEsession.commit()def check_out(cartId):if cartId is None:raise ShoppingCartException(101, "Cart id not specified")cart = Cart.get_by(id = cartId)if cart is None:raise ShoppingCartException(102, "The specified cart couldn't be found")cart.checked_out_on = datetime.datetime.now()session.commit()return Truedef reset_cart(cartId, items):if cartId is None:raise ShoppingCartException(101, "Cart id not specified")for item_id, quantity in items.iteritems():line = Line.query.filter_by(cart_id=cartId, item_id=item_id).one()if line is not None:delete_discounts_for_line(line)line.discounted_price = Noneline.quantity = line.quantity - quantityif line.quantity == 0:line.delete()cart = Cart.get_by(id=cartId)cart.updated_on = datetime.datetime.now()cart.checked_out_on = None# Removing Couponcart.total_price = Nonecart.discounted_price = Nonecart.coupon_code = Nonesession.commit()return Truedef get_carts_with_coupon_count(coupon_code):return Cart.query.filter_by(coupon_code = coupon_code).count()def show_cod_option(cartId, sourceId, pincode):cart = Cart.get_by(id = cartId)cod_option = Truelogistics_client = LogisticsClient().get_client()if cart:if cart.coupon_code:promotion_client = PromotionClient().get_client()cod_option = promotion_client.isCodApplicable(cart.coupon_code)if cod_option and cart.lines:for line in cart.lines:logistics_info = logistics_client.getLogisticsEstimation(line.item_id, pincode, DeliveryType.PREPAID)if not logistics_info.codAllowed:cod_option = Falsebreakif cart.total_price > 20000 or cart.total_price <= 250:cod_option = Falsereturn cod_optiondef close_session():if session.is_active:print "session is active. closing it."session.close()