Subversion Repositories SmartDukaan

Rev

Rev 5464 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.user.handler;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import in.shop2020.logistics.DeliveryType;
import in.shop2020.logistics.LogisticsInfo;
import in.shop2020.logistics.LogisticsService;
import in.shop2020.logistics.LogisticsServiceException;
import in.shop2020.model.v1.catalog.InventoryService;
import in.shop2020.model.v1.catalog.InventoryServiceException;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.ItemShippingInfo;
import in.shop2020.model.v1.order.LineItem;
import in.shop2020.model.v1.order.Order;
import in.shop2020.model.v1.order.OrderStatus;
import in.shop2020.model.v1.order.Transaction;
import in.shop2020.model.v1.order.TransactionService;
import in.shop2020.model.v1.order.TransactionServiceException;
import in.shop2020.model.v1.order.TransactionStatus;
import in.shop2020.model.v1.user.CartStatus;
import in.shop2020.model.v1.user.Discount;
import in.shop2020.model.v1.user.LineStatus;
import in.shop2020.model.v1.user.PromotionException;
import in.shop2020.model.v1.user.PromotionService;
import in.shop2020.model.v1.user.ShoppingCartException;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.LogisticsClient;
import in.shop2020.thrift.clients.PromotionClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.user.domain.Address;
import in.shop2020.user.domain.Cart;
import in.shop2020.user.domain.Line;
import in.shop2020.user.persistence.CartMapper;
import in.shop2020.user.util.Converter;

@Service
public class CartHandler {

        @Autowired
        private CartMapper cartMapper;
        @Autowired
        private AddressHandler addressHandler;
        @Autowired
        private UserHandler userHandler;
        
        private static final Log log = LogFactory.getLog(CartHandler.class);
        
        public Cart createCart() throws TException{
                log.info("Creating new cart");
                Cart cart = new Cart();
                cart.setCart_status(CartStatus.ACTIVE.getValue());
                cart.setCreated_on(new Date());
                cart.setUpdated_on(new Date());
                cartMapper.createCart(cart);
                return cart;
        }

        public in.shop2020.model.v1.user.Cart getCart(long id) throws TException{
                return Converter.toThriftCart(cartMapper.getCart(id));
        }

        public in.shop2020.model.v1.user.Cart getCartsForUser(long userId,
                CartStatus status) throws ShoppingCartException, TException{
                if(userId == 0 || userId == -1) {
                        log.error("UserId : "+userId+"incorrect to get cart");
                        throw new ShoppingCartException(101, "user_id is not provided");
                }
                in.shop2020.model.v1.user.User user = userHandler.getUserById(userId);
                return Converter.toThriftCart(cartMapper.getCart(user.getActiveCartId()));
        }

        public void changeCartStatus(long cartId, CartStatus status) throws TException{
                cartMapper.changeCartStatus(cartId, status.getValue());
        }

        public List<in.shop2020.model.v1.user.Cart> getCartsByStatus(
                CartStatus status) throws TException{
                List<Cart> carts = cartMapper.getCartsByStatus(status.getValue());
                if(carts!=null) {
                        List<in.shop2020.model.v1.user.Cart> tCarts = new ArrayList<in.shop2020.model.v1.user.Cart>();
                        for(Cart cart : carts) {
                                tCarts.add(Converter.toThriftCart(cart));
                        }
                        return tCarts;
                }
                log.warn("No carts found for cartStatus : "+status);
                return null;
        }

        public List<in.shop2020.model.v1.user.Cart> getCartsByTime(long from_time,
                long to_time, CartStatus status) throws TException{
                List<Cart> carts = cartMapper.getCartsByTime(from_time, to_time, status.getValue());
                if(carts!=null) {
                        List<in.shop2020.model.v1.user.Cart> tCarts = new ArrayList<in.shop2020.model.v1.user.Cart>();
                        for(Cart cart : carts) {
                                tCarts.add(Converter.toThriftCart(cart));
                        }
                        return tCarts;
                }
                log.warn("Couldn't get carts in specified time ");
                return null;
        }

        public void deleteItemFromCart(long cartId, long itemId) 
        throws ShoppingCartException, TException{
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found with Id : "+cartId);
                                throw new ShoppingCartException(101, "no cart attached to this id");
                        } else {
                                Line lineItem = cartMapper.getLine(itemId, cartId, -1);
                                if(lineItem!=null) {
                                        cartMapper.deleteDiscountForLine(cartId, itemId);
                                        cartMapper.deleteLine(cartId, itemId);
                                        cartMapper.updateCartUpdatedTime(new Date(), cartId);
                                }
                        }
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public long getCartsWithCouponCount(String couponCode) throws TException{
                        return cartMapper.getCartsWithCouponCount(couponCode);
        }

        public void changeItemStatus(long cartId, long itemId, LineStatus status) 
                throws ShoppingCartException, TException{
                try {
                        if(status == null) {
                                log.error("LineStatus cannot be null for Item : " + itemId + 
                                                "cart : "+cartId);
                                throw new ShoppingCartException(101, "Status cannot be made null");
                        }
                        Line line = cartMapper.getLine(itemId, cartId, -1);
                        if(line!=null) {
                                line.setLine_status(status.getValue());
                                line.setUpdated_on(new Date());
                                cartMapper.updateLine(line);
                                cartMapper.updateCartUpdatedTime(new Date(), cartId);
                        } else {
                                log.error("Unable to probe the line you desired");
                                throw new ShoppingCartException(101, "Unable to probe the line you desired");
                        }
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public void addAddressToCart(long cartId, long addressId) 
                throws ShoppingCartException, TException{
                try {
                        if(cartId == 0 ) {
                                log.error("CartId cannot be 0");
                                throw new ShoppingCartException(101, "cart id cannot be empty");
                        }
                        if(addressId == 0) {
                                log.error("AddressId cannot be 0");
                                throw new ShoppingCartException(101, "Address id cannot be empty");
                        }
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : " + cartId);
                                throw new ShoppingCartException(101, "no cart for this id");
                        }
                        in.shop2020.user.domain.Address address = addressHandler.getAddress(addressId);
                        if(address == null) {
                                log.error("No address found for Id : " + addressId);
                                throw new ShoppingCartException(101, "No address for this id");
                        }
                        cartMapper.addAddressToCart(cartId, addressId);
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public boolean checkOut(long cartId) throws ShoppingCartException, TException{
                try {
                        if(cartId == 0){
                        log.error("CartId cannot be 0");
                        throw new ShoppingCartException(101, "Cart id not specified");
                        }
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : " + cartId);
                                throw new ShoppingCartException(102, "The specified cart couldn't be found");
                        }
                        cartMapper.updateCartUpdatedTime(new Date(), cartId);
                        return true;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }
        
        public void saveDiscounts(List<Discount> discounts) 
                throws ShoppingCartException, TException{
                try {
                        if(discounts == null||discounts.size() == 0) {
                                log.error("Discounts cannot be empty");
                                throw new ShoppingCartException(101, "discounts cannot be null");
                        }
                        if(discounts.size()>0) {
                                in.shop2020.user.domain.Cart cart = cartMapper.getCart(discounts.get(0).getCart_id());
                                for(Discount tDiscount : discounts) {
                                        in.shop2020.user.domain.Line line = cartMapper.getLine(tDiscount.getItem_id(), cart.getId(), -1);
                                        if(line!=null) {
                                                in.shop2020.user.domain.Discount discount = new in.shop2020.user.domain.Discount();
                                                discount.setLine_cart_id(line.getCart_id());
                                                discount.setLine_item_id(tDiscount.getItem_id());
                                                discount.setDiscount(tDiscount.getDiscount());
                                                discount.setQuantity(tDiscount.getQuantity());
                                                cartMapper.insertDiscount(discount);
                                        }
                                }
                        }
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public void applyCouponToCart(long cartId, String couponCode,
                double totalPrice, double discountedPrice) throws ShoppingCartException, TException{
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : " + cartId);
                                throw new ShoppingCartException(101, "no cart attached to this id");
                        }
                        cart.setTotal_price(totalPrice);
                        cart.setDiscounted_price(discountedPrice);
                        cart.setCoupon_code(couponCode);
                        cartMapper.updateCart(cart);
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public void removeCoupon(long cartId) throws ShoppingCartException, TException{
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : " + cartId);
                                throw new ShoppingCartException(101, "no cart attached to this id");
                        }
                        for(in.shop2020.user.domain.Line line : cart.getLines()) {
                                cartMapper.removeLineDiscount(cart.getId(), line.getItem_id());
                        }
                        
                        deleteDiscountsFromCart(cart.getId());
                    cart.setDiscounted_price(0);
                    cart.setCoupon_code(null);
                    cartMapper.updateCart(cart);
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public String addItemToCart(long cartId, long itemId, long quantity,
                long sourceId) throws ShoppingCartException, TException {
                try {
                        if(itemId == 0) {
                                log.error("ItemId cannot be 0");
                                throw new ShoppingCartException(101, "item_id cannot be 0");
                        }
                        if(quantity == 0) {
                                log.error("quantity cannot be 0");
                                throw new ShoppingCartException(101, "quantity cannot be null");
                        }
        
                        Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : " + cartId);
                                throw new ShoppingCartException(101, "no cart attached to this id");
                        }
                        Item item;
                        try {
                                InventoryService.Client catalogClient = new CatalogClient().getClient();
                                item = catalogClient.getItemForSource(itemId, sourceId);
                                ItemShippingInfo itemShippingInfo = catalogClient.isActive(itemId);
                                if(!itemShippingInfo.isIsActive()) {
                                        return catalogClient.getItemStatusDescription(itemId);
                                }
                        } catch(InventoryServiceException ex) {
                                log.error("InventoryServiceException while getting item ");
                                try {
                                        InventoryService.Client catalogClient = new CatalogClient().getClient();
                                        item = catalogClient.getItemForSource(itemId, sourceId);
                                        ItemShippingInfo itemShippingInfo = catalogClient.isActive(itemId);
                                        if(!itemShippingInfo.isIsActive()) {
                                                return catalogClient.getItemStatusDescription(itemId);
                                        } 
                                } catch(InventoryServiceException e) {
                                        log.error("InventoryServiceException while getting item ");
                                        throw new TException("InventoryServiceException caught in adding Item to Cart"+e);
                                }
                        }
                                
                                cartMapper.updateCartUpdatedTime(new Date(), cartId);
                                Line line = cartMapper.getLine(itemId, cartId, -1);
                                if(line==null) {
                                        line = new Line();
                                        line.setCart_id(cartId);
                                        line.setItem_id(itemId);
                                        line.setQuantity(quantity);
                                        line.setCreated_on(new Date());
                                        line.setUpdated_on(new Date());
                                        line.setActual_price(item.getSellingPrice());
                                        line.setLine_status(LineStatus.LINE_ACTIVE.getValue());
                                        cartMapper.insertLine(line);
                                } else {
                                        cartMapper.updateLineQuantity(quantity, cartId, itemId, new Date());
                                }
                        
                        return "";
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public boolean showCODOption(long cartId, long sourceId, String pincode) throws TException {
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        boolean codOption = true;
                        try{
                                if(cart!=null) {
                                        if(cart.getCoupon_code() != null && cart.getCoupon_code().toLowerCase().equals("searlybird")) {
                                                codOption = false;
                                        } else if(cart.getLines()!=null){
                                                for(Line line : cart.getLines()) {
                                                        LogisticsService.Client logisticsClient = new LogisticsClient().getClient();
                                                        LogisticsInfo logisticsInfo = logisticsClient.
                                                                getLogisticsEstimation(line.getItem_id(), pincode, DeliveryType.PREPAID);
                                                        if(!logisticsInfo.isCodAllowed()){
                                                                codOption = false;
                                                                break;
                                                        }
                                                }
                                    if(cart.getTotal_price() > 20000 || cart.getTotal_price() <= 250)
                                        codOption = false;
                                        }
                                }
                        }catch(LogisticsServiceException ex) {
                                log.error("Error in getting COD option");
                                codOption = false;
                        }
                        return codOption;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public void deleteDiscountsFromCart(long cartId) throws ShoppingCartException, TException{
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : "+cartId);
                                throw new ShoppingCartException(101, "No cart found for Id : "+cartId);
                        }
                        if(cart.getLines()!=null && !cart.getLines().isEmpty()) {
                                for(in.shop2020.user.domain.Line line : cart.getLines()) {
                                        deleteDiscountsForLine(cart.getId(), line.getItem_id());
                                }
                        } else {
                                log.info("No lines found for cart : " + cartId);
                        }
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        private void deleteDiscountsForLine(long cartId, long itemId) throws TException{
                        cartMapper.deleteDiscountForLine(cartId, itemId);
        }

        @Transactional
        public boolean resetCart(long cartId, Map<Long, Double> items) throws TException{
                try {
                        Set<Long> itemIds = new HashSet<Long>();
                        itemIds = items.keySet(); 
                        for(Long itemId : itemIds) {
                                in.shop2020.user.domain.Line line = cartMapper.getLine(itemId, cartId, 0);
                                if(line!=null) {
                                        deleteDiscountsForLine(cartId, itemId);
                                        if((line.getQuantity() - items.get(itemId)) == 0) {
                                                cartMapper.deleteDiscountForLine(line.getCart_id(), line.getItem_id());
                                                cartMapper.deleteLine(line.getCart_id(), line.getItem_id());
                                        } else {
                                                line.setQuantity(line.getQuantity() - items.get(itemId));
                                                line.setDiscounted_price(0);
                                                cartMapper.updateLine(line);
                                        }
                                }
                        }
                        
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        cart.setUpdated_on(new Date());
                        cart.setChecked_out_on(null);
                        cart.setTotal_price(0);
                        cart.setDiscounted_price(0);
                        cart.setCoupon_code(null);
                        cartMapper.updateCart(cart);
                        return true;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }
        
        @Transactional
        public void mergeCart(long fromCartId, long toCartId) throws TException{
                try {
                        in.shop2020.user.domain.Cart fromCart = cartMapper.getCart(fromCartId);
                        in.shop2020.user.domain.Cart toCart = cartMapper.getCart(toCartId);
                        
                        List<in.shop2020.user.domain.Line> fromLines = new ArrayList<in.shop2020.user.domain.Line>();
                        List<in.shop2020.user.domain.Line> toLines = new ArrayList<in.shop2020.user.domain.Line>();
                        fromLines = fromCart.getLines();
                        toLines = toCart.getLines();
        
                        for (Line line : fromLines) {
                                for(in.shop2020.user.domain.Discount discount : line.getDiscounts()) {
                                        cartMapper.deleteDiscountForLine(discount.getLine_cart_id(), discount.getLine_item_id());
                                }
                        }
                        
                        for(Line line : fromLines) {
                                boolean flag = true;
                                for(Line toLine : toLines) {
                                        if(line.getItem_id() == toLine.getItem_id()) {
                                                flag = false;
                                        }
                                }
                                if(flag) {
                                        line.setCart_id(toCartId);
                                        cartMapper.changeCartIdForLine(fromCartId, line.getItem_id(), toCartId);
                                } else {
                                        cartMapper.deleteDiscountForLine(fromCartId, line.getItem_id());
                                        cartMapper.deleteLine(fromCartId,line.getItem_id());
                                }
                        }
                        
                        if(toCart.getCoupon_code()==null) {
                                toCart.setCoupon_code(fromCart.getCoupon_code());
                        }
                        toCart.setUpdated_on(new Date());
                        cartMapper.updateCart(toCart);
                        cartMapper.deActivateCart(fromCart.getId());
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public String validateCart(long cartId, long sourceId) throws TException, ShoppingCartException {
                try {
                        String 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 = cartMapper.getCart(cartId);
                        List<Line> lines = cart.getLines();
                        String pincode = null;
                        Date currentTime = new Date();
                        if(cart.getAddress_id()!=0) {
                                Address address = addressHandler.getAddress(cart.getAddress_id());
                                pincode = address.getPin();
                        }
                        if(null == pincode) {
                                in.shop2020.model.v1.user.User user = userHandler.getUserByCartId(cartId);
                                long addressId = user.getDefaultAddressId();
                                pincode = addressHandler.getPincodeForAddress(addressId);
                        }
                        if(pincode == null) {
                                pincode = "110001";
                        }
                        cart.setTotal_price(0);
                        for(Line line : lines) {
                                int oldEstimate = line.getEstimate();
                                long itemId = line.getItem_id();
                                line.setCart_id(cartId);
                                Item item;
                                ItemShippingInfo itemShippingInfo;
                                try {
                                        InventoryService.Client inventoryClient = new CatalogClient().getClient();
                                        item = inventoryClient.getItemForSource(itemId, sourceId);
                                        itemShippingInfo = inventoryClient.isActive(itemId);
                                } catch(InventoryServiceException invEx) {
                                        log.error("Exception in getting item and itemShippingInfo" +
                                                        "inventory Service");
                                        throw new ShoppingCartException(101, invEx.getMessage());
                                }
                                if(itemShippingInfo.isIsActive()) {
                                        long itemDeliveryEstimate;
                                        if(itemShippingInfo.isIsRisky() && itemShippingInfo.getQuantity()<line.getQuantity()) {
                                                line.setQuantity(1);
                                                retval = "Try adding a smaller quantity of " + item.getBrand() +
                                                                " " + item.getModelNumber() + " (" + item.getColor() + ")";
                                        }
                                        line.setActual_price(item.getSellingPrice());
                                        cart.setTotal_price(cart.getTotal_price() + (line.getActual_price()*line.getQuantity()));
                                        try {
                                                LogisticsService.Client logisticsClient = new LogisticsClient().getClient();
                                                itemDeliveryEstimate = logisticsClient.getLogisticsEstimation(itemId, pincode, DeliveryType.PREPAID).getDeliveryTime();
                                        } catch(LogisticsServiceException ex) {
                                                log.error("Exception while delivery estimates for item:" +
                                                                ""+itemId+" & pincode:"+pincode +"\n"+ex);
                                                itemDeliveryEstimate = -1;
                                        } catch(Exception e) {
                                                log.error("Exception while delivery estimates for item:" +
                                                                ""+itemId+" & pincode:"+pincode +"\n"+e);
                                itemDeliveryEstimate = -1;
                                        }
                                        if(oldEstimate!=itemDeliveryEstimate) {
                                                line.setEstimate((int)itemDeliveryEstimate);
                                                cart.setUpdated_on(new Date());
                                                if(oldEstimate!=-1||oldEstimate!=0) {
                                                        retval = "Delivery Estimates updated.";
                                                }
                                        }
                                } else {
                                        cartMapper.deleteDiscountForLine(line.getCart_id(), line.getItem_id());
                                        cartMapper.deleteLine(line.getCart_id(), line.getItem_id());
                                        retval = "Some items have been removed from the cart.";
                                }
                        }
                        
                        if(cart.getChecked_out_on()!=null && cart.getUpdated_on()!=null) {
                                if(cart.getUpdated_on().getTime()>cart.getChecked_out_on().getTime()) {
                                        cart.setChecked_out_on(null);
                                        if(retval.equals("")) {
                                                retval = "Your cart has been updated after the last checkout.";
                                        }
                                }
                        }
                        cartMapper.updateCart(cart);
                        for(Line line : lines) {
                                line.setCart_id(cartId);
                                cartMapper.updateLine(line);
                        }
                        if(cart.getCoupon_code()!=null) {
                                try {
                                        PromotionService.Client promotionClient = new PromotionClient().getClient();
                                        in.shop2020.model.v1.user.Cart tCart = promotionClient.applyCoupon(cart.getCoupon_code(), cart.getId());
                                        for(in.shop2020.model.v1.user.Line tLine : tCart.getLines()) {
                                                Line line  = cartMapper.getLine(tLine.getItemId(), tCart.getId(), -1);
                                                line.setDiscounted_price(tLine.getDiscountedPrice());
                                        }
                                        cart.setDiscounted_price(tCart.getDiscountedPrice());
                                        
                                        cartMapper.updateCart(cart);
                                        for(Line line : lines) {
                                                cartMapper.updateLine(line);
                                        }
                                } catch (PromotionException ex) {
                                        log.error("PromotionException while applying coupon "+cart.getCoupon_code()+ex);
                                        removeCoupon(cart.getId());
                                        retval = ex.getMessage();
                                }
                        }
                        return retval;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        public long commitCart(long cartId, String sessionSource,
                        long sessionStartTime, String firstSource, long firstSourceTime,
                        long userId) throws  TException, ShoppingCartException {
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        
                        Transaction transaction = new Transaction();
                        transaction.setShoppingCartid(cartId);
                        transaction.setCustomer_id(userId);
                        transaction.setCreatedOn(new Date().getTime());
                        transaction.setTransactionStatus(TransactionStatus.INIT);
                        transaction.setStatusDescription("New Order");
                        transaction.setCoupon_code(cart.getCoupon_code());
                        transaction.setSessionSource(sessionSource);
                        transaction.setSessionStartTime(sessionStartTime);
                        transaction.setFirstSource(firstSource);
                        transaction.setFirstSourceTime(firstSourceTime);
                        transaction.setOrders(createOrders(cart,userId));
                        try{
                                TransactionService.Client transactionClient = new TransactionClient().getClient();
                                return transactionClient.createTransaction(transaction);
                        } catch(TransactionServiceException txnEx) {
                                log.error("TransactionServiceException while creating Transa caction ");
                                try {
                                        TransactionService.Client transactionClient = new TransactionClient().getClient();
                                        return transactionClient.createTransaction(transaction);
                                } catch(TransactionServiceException txnE) {
                                        log.error("TransactionServiceException while creating Transa caction ");
                                        throw new ShoppingCartException(101, txnE.getMessage());
                                }
                        }
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        private List<Order> createOrders(Cart cart, long userId) throws TException {
                try {
                        List<Line> cartLine = cart.getLines();
                        List<Order> orders = new ArrayList<Order>();
                        double quantityRemainingForOrder;
        
                        for(Line line : cartLine) {
                                if(line.getLine_status() == LineStatus.LINE_ACTIVE.getValue()) {
                                        quantityRemainingForOrder = line.getQuantity();
                                        List<in.shop2020.user.domain.Discount> discounts = line.getDiscounts();
                                        if(discounts!=null) {
                                                log.info("Discount not null");
                                                for(in.shop2020.user.domain.Discount discount : discounts) {
                                                        log.info(discount.getLine_item_id());
                                                        int i = 0;
                                                        while(i<discount.getQuantity()) {
                                                                LineItem tLineItem = createLineItem(line.getItem_id(), line.getActual_price()-discount.getDiscount());
                                                                Order order = createOrder(userId, cart.getAddress_id(), tLineItem);
                                                                orders.add(order);
                                                                i++;
                                                        }
                                                        quantityRemainingForOrder = quantityRemainingForOrder - discount.getQuantity();
                                                }
                                        }
                                        int i=0;
                                        while(i<quantityRemainingForOrder) {
                                                LineItem tLineItem = createLineItem(line.getItem_id(), line.getActual_price());
                                Order order = createOrder(userId, cart.getAddress_id(), tLineItem);
                                orders.add(order);
                                i += 1;
                                        }
                                }
                        }
                        return orders;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        private Order createOrder(long userId, long addressId, LineItem tLine) throws TException{
                try {
                        in.shop2020.model.v1.user.User user = userHandler.getUserById(userId);
                        Address address = addressHandler.getAddress(addressId);
                        Order order = new Order();
                        order.setCustomer_id(user.getUserId());
                        order.setCustomer_email(user.getEmail());
                        order.setCustomer_name(address.getName());
                        order.setCustomer_pincode(address.getPin());
                        order.setCustomer_address1(address.getLine_1());
                        order.setCustomer_address2(address.getLine_2());
                        order.setCustomer_city(address.getCity());
                        order.setCustomer_state(address.getState());
                        order.setCustomer_mobilenumber(address.getPhone());
                        order.setTotal_amount(tLine.getTotal_price());
                        order.setTotal_weight(tLine.getTotal_weight());
                        List<LineItem> lineItems = new ArrayList<LineItem>();
                        lineItems.add(tLine);
                        order.setLineitems(lineItems);
                        order.setStatus(OrderStatus.PAYMENT_PENDING);
                        order.setStatusDescription("Payment Pending");
                        order.setCreated_timestamp(new Date().getTime());
                    return order;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }

        private LineItem createLineItem(long item_id, double finalPrice) throws TException {
                double quantity=1;
                try {
                        InventoryService.Client inventoryClient;
                        Item item = null;
                        try {
                                inventoryClient = new CatalogClient().getClient();
                                item = inventoryClient.getItem(item_id);
                        } catch (TTransportException e) {
                                log.warn("Retrying to create Line Item, Failed first time"+e);
                                try {
                                        inventoryClient = new CatalogClient().getClient();
                                        item = inventoryClient.getItem(item_id);
                                } catch(TTransportException ex) {
                                        log.error("Error while getting item from inventory");
                                        throw new TException("Exception while creating line item"+ex);
                                } catch (InventoryServiceException exx) {
                                        log.error("Error while getting item from inventory"+exx);
                                        throw new TException("Exception while creating line item"+exx);
                                }
                        } catch(InventoryServiceException invEx) {
                                log.error("Error while creating line item "+invEx);
                                throw new TException("Exception while creating line item"+invEx);
                        }
                        LineItem tLineItem = new LineItem();
                        tLineItem.setProductGroup(item.getProductGroup());
                        tLineItem.setBrand(item.getBrand());
                        tLineItem.setModel_number(item.getModelNumber());
                        if(item.getColor()==null || item.getColor().equals("N/A")) {
                                tLineItem.setColor("");
                        } else {
                                tLineItem.setColor(item.getColor());
                        }
                        tLineItem.setModel_name(item.getModelName());
                        tLineItem.setExtra_info(item.getFeatureDescription());
                        tLineItem.setItem_id(item.getId());
                        tLineItem.setQuantity(quantity);//TODO Quantity always 1
                        tLineItem.setUnit_price(finalPrice);
                        tLineItem.setTotal_price(finalPrice*quantity);
                        tLineItem.setUnit_weight(item.getWeight());
                        tLineItem.setTotal_weight(item.getWeight()*quantity);
                        tLineItem.setDealText(item.getBestDealText());
        
                        if(item.getWarrantyPeriod()!=0) {
                                Date today = new Date();
                                Date expiryDate;
                                int expiryYear = today.getYear() + (int)((today.getMonth() + item.getWarrantyPeriod())/12);
                                int expiryMonth = (today.getMonth() + item.getWarrantyPeriod()) % 12;
                                try  {
                                        expiryDate = new Date(expiryYear, expiryMonth, today.getDate(), 23, 59, 59); //Milliseconds
                                } catch (Exception e) {
                                        try {
                                expiryDate = new Date(expiryYear, expiryMonth, (today.getDate() - 1), 23, 59, 59);
                                        } catch (Exception ex) {
                                try {
                                    expiryDate = new Date(expiryYear, expiryMonth, (today.getDate() - 2), 23, 59, 59);
                                } catch (Exception exc) {
                                    expiryDate = new Date(expiryYear, expiryMonth, (today.getDate() - 3), 23, 59, 59);
                                }
                                        }
                                }
                                tLineItem.setWarrantry_expiry_timestamp(expiryDate.getTime());
                        }
                                
                    return tLineItem;
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }
        }


        void addStoreToCart(long cartId, long storeId) throws TException{
                try {
                        in.shop2020.user.domain.Cart cart = cartMapper.getCart(cartId);
                        if(cart == null) {
                                log.error("No cart found for Id : "+cartId);
                                throw new ShoppingCartException(101, "No cart found for Id : "+cartId);
                        }
                        
                        if(storeId != 0){
                                cart.setPickupStoreId(storeId);
                        }else{
                                cart.setPickupStoreId(0);
                        }
                        cartMapper.updateCart(cart);
                } catch(Exception e) {
                        log.error(e);
                        throw new TException(e.getMessage(), e);
                }

        }
}