Subversion Repositories SmartDukaan

Rev

Rev 563 | Rev 612 | 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
from shop2020.thriftpy.model.v1.user.ttypes import CartStatus, LineStatus, ShoppingCartException
import datetime
from shop2020.utils.Utils import to_py_date, to_java_date

from shop2020.thriftpy.model.v1.order.ttypes import Transaction as TTransaction,\
    TransactionStatus as TTransactionStatus, Order as TOrder, LineItem as TLineItem,\
    PaymentInfo as TPaymentInfo, OrderStatus 

from shop2020.thriftpy.model.v1.catalog.ttypes import Item as TItem
from shop2020.thriftpy.logistics.ttypes import LogisticsInfo as TLogisticsInfo

from shop2020.clients.TransactionClient import TransactionClient
from shop2020.clients.InventoryClient import InventoryClient
from shop2020.clients.LogisticsClient import LogisticsClient
from shop2020.model.v1 import user

def get_cart(user_id):
    query = Cart.query.filter_by(user_id=user_id)      
    query = query.filter_by(cart_status = CartStatus.ACTIVE)
    try:
        cart = query.one()
        cart.accessed_on = datetime.datetime.now()
        session.commit()
    except:
        return None
#        raise ShoppingCartException(101, "Cart does not exist")
    return cart

def get_cart_by_id(id):
    cart = Cart.get_by(id=id)
    if cart:
        cart.accessed_on = datetime.datetime.now()
        session.commit()
    return cart

def create_cart(user_id):
    cart = get_cart(user_id)
    if not cart: 
        cart = Cart()
        cart.user_id = user_id
        cart.created_on = datetime.datetime.now()
        cart.updated_on = datetime.datetime.now()
        cart.cart_status = CartStatus.ACTIVE
        session.commit()
    
    return cart

def get_cart_by_user_id_and_status(user_id, status):

    query = Cart.query.filter_by(user_id=user_id)
    if status:
        query = query.filter_by(cart_status=status)
    carts = query.all()
    return carts

def get_carts_by_status(status):
    return Cart.query.filter_by(cart_status=status).all()


def get_carts_between(start_time, end_time, status):
    init_time = to_py_date(start_time)
    finish_time = to_py_date(end_time)
    
    query = Cart.query
    if 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 carts

def get_item(item_id, cart_id, status, single):
    
    #get cart first 
    try:
        found_cart = Cart.get_by(id=cart_id)
        
    except:
        raise ShoppingCartException(101, "cart not found ")
    query = Line.query.filter(Line.cart.has(id = cart_id))
    query = query.filter_by(item_id = item_id)
    
#    query = LineItem.query.filter_by(item_id = item_id)
#    query = query.filter(LineItem.cart.id == cart_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 None

def get_item_by_id(line_id):
    return Line.get_by(id=line_id)

def change_cart_status(cart_id, status):
    cart = get_cart_by_id(id)
    if not cart:
        raise ShoppingCartException(101, "no cart attached to this id")
    if not status:
        raise ShoppingCartException(101, "invalid status")
    
    cart.cart_status = status
     
    session.commit()
    
def add_item_to_cart(cart_id, item_id, quantity):
    if not item_id:
        raise ShoppingCartException(101, "item_id cannot be null")
    
    if not quantity:
        raise ShoppingCartException(101, "quantity cannot be null")    
    
    item = get_item(item_id, cart_id, None,True)
    if item:
        #change the quantity only
        item.quantity = quantity
        session.commit()
        return item.id
    
    cart = get_cart_by_id(cart_id)
    if not cart:
        raise ShoppingCartException(101, "no cart attached to this id")
    
    line = Line()
    line.item_id = item_id
    line.quantity = quantity
    line.created_on = datetime.datetime.now()
    line.updated_on = datetime.datetime.now()
    line.line_status = LineStatus.LINE_ACTIVE
    
    cart.lines.append(line)
    session.commit()
    return line.id

def delete_item_from_cart(cart_id, item_id):
    if not item_id:
        raise ShoppingCartException(101, "item_id cannot be null")
    item = get_item(item_id, cart_id, None, True)
    item.delete()
    session.commit()
    return

def change_item_quantity(cart_id, item_id, quantity):
    return add_item_to_cart(cart_id, item_id, quantity)

def change_item_status(cart_id, item_id, status):
    if not status:
        raise ShoppingCartException(101, "Status cannot be made null")
    item = get_item(item_id, cart_id, None, True)
    if item:
        item.line_status = status
        session.commit()
    else:
        raise ShoppingCartException(101, "Unable to probe the item you desired")
    
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_id
    session.commit()
    
def commit_cart(cart_id):   
    cart = get_cart_by_id(cart_id)
    cart.cart_status = CartStatus.COMMITTED
    cart.committed_on = datetime.datetime.now()
    
    #now we have a cart. Need to create a transaction with it
    txn = TTransaction()
    txn.paymentInfo = TPaymentInfo()
    txn.shoppingCartid = cart_id
    txn.customer_id = cart.user_id
    txn.createdOn = to_java_date(datetime.datetime.now())
    txn.transactionStatus = TTransactionStatus.INIT
    txn.statusDescription = "New Order"
    
    txn.orders = create_orders(cart)
    
    transaction_client = TransactionClient().get_client()
    txn_id = transaction_client.createTransaction(txn)
    session.commit()
    
    new_cart = create_cart(cart.user_id)
    user = User.get_by(id=cart.user_id)
    user.active_cart_id = new_cart.id
    session.commit()
    return txn_id

def create_orders(cart):
    cart_lines = cart.lines
    orders = []
    
    for line in cart_lines:
        if line.line_status == LineStatus.LINE_ACTIVE:
            i = 0
            while i< line.quantity:
                t_line_item = create_line_item(line.item_id)
                t_order = create_order(cart.user_id, cart.address_id, t_line_item)
                orders.append(t_order)
                i += 1
    return orders

def create_order(user_id, address_id, t_line_item):
    user = User.get_by(id=user_id)
    address = Address.get_by(id=address_id)
    t_order = TOrder()
    
    t_order.customer_id = user.id
    t_order.customer_name = user.name
    t_order.customer_email = user.email
    
    t_order.customer_pincode = address.pin
    t_order.customer_address = get_address_string(address)
    t_order.customer_mobilenumber = address.phone
    
    t_order.total_amount = t_line_item.total_price
    t_order.total_weight = t_line_item.total_weight
    t_order.lineitems = [t_line_item]
    
    t_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
    t_order.statusDescription = "Submitted to warehouse"
    t_order.created_timestamp = to_java_date(datetime.datetime.now())
    
    logistics_client = LogisticsClient().get_client()
    logistics_info = logistics_client.getLogisticsInfo(t_order.customer_pincode, t_line_item.sku_id)
    
    t_order.logistics_provider_id = logistics_info.provider_id
    t_order.airwaybill_no = logistics_info.airway_billno
    t_order.tracking_id = t_order.airwaybill_no
    t_order.expected_delivery_time = to_java_date(datetime.datetime.now()) + 60*60*1000*logistics_info.delivery_estimate
    t_order.warehouse_id = logistics_info.warehouse_id

    return t_order
        
def create_line_item(catalog_item_id):
    inventory_client = InventoryClient().get_client()
    catalog_item = inventory_client.getItemByCatalogId(catalog_item_id)
    t_line_item = TLineItem()
    t_line_item.model_name = catalog_item.modelName
    t_line_item.model_number = catalog_item.modelNumber
    t_line_item.extra_info = catalog_item.featureDescription
    t_line_item.brand = catalog_item.manufacturerName
    t_line_item.sku_id = catalog_item.vendorItemId
    t_line_item.quantity = 1
    t_line_item.unit_price = catalog_item.sellingPrice
    t_line_item.unit_weight = catalog_item.weight
    t_line_item.total_price = catalog_item.sellingPrice
    t_line_item.total_weight = catalog_item.weight
    return t_line_item

def get_address_string(address):
    return address.line_1 + "\n" + address.line_2 + "\nLandmark: " + address.landmark + "\n" + address.city + "\n" + address.state + "\n" + address.country
    
def validate_cart(cartId):
    inventory_client = InventoryClient().get_client()
    logistics_client = LogisticsClient().get_client()
    retval = True
    # 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)
    old_estimate = cart.estimate
    new_estimate = 0
    cart_lines = cart.lines
    customer_pincode = ""
    if cart.address_id:
        address = Address.get_by(id=cart.address_id)
        customer_pincode = address.pin
    for line in cart_lines:
        catalog_item_id = line.item_id
        if inventory_client.isActive(catalog_item_id):
            if customer_pincode:
                #FIXME: Provider ID should be returned by the same call and shouldn't be hard-coded as 1
                item_delivery_estimate = logistics_client.getLogisticsEstimation(catalog_item_id, customer_pincode, 1).shippingTime 
                if new_estimate < item_delivery_estimate:
                    new_estimate = item_delivery_estimate
        else:
            line.delete()
            retval = False

    if new_estimate != old_estimate:
        cart.estimate = new_estimate
        session.commit()
        retval = False
    return retval

def merge_cart(fromCartId, toCartId):
    fromCart = Cart.get_by(id=fromCartId)
    toCart = Cart.get_by(id=toCartId)
    
    old_lines = fromCart.lines
    new_lines = toCart.lines
    
    for line in old_lines:
        flag = True
        for new_line in new_lines:
            if line.item_id == new_line.item_id:
                flag = False
        if flag:
            toCart.lines.append(line)

    toCart.updatedOn = datetime.datetime.now() 
    
    fromCart.expired_on = datetime.datetime.now()
    fromCart.cart_status = CartStatus.INACTIVE
    session.commit()