Subversion Repositories SmartDukaan

Rev

Rev 3264 | Rev 3616 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.serving.controllers;

import in.shop2020.datalogger.EventType;
import in.shop2020.model.v1.order.Order;
import in.shop2020.model.v1.user.Address;
import in.shop2020.model.v1.user.ShoppingCartException;
import in.shop2020.serving.interceptors.TrackingInterceptor;
import in.shop2020.serving.services.CodPaymentService;
import in.shop2020.serving.services.CommonPaymentService;
import in.shop2020.serving.services.EbsPaymentService;
import in.shop2020.serving.services.HdfcPaymentService;
import in.shop2020.serving.services.IPaymentService;
import in.shop2020.serving.utils.DesEncrypter;
import in.shop2020.serving.utils.Utils;
import in.shop2020.thrift.clients.LogisticsClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.UserClient;
import in.shop2020.utils.DataLogger;

import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import javax.servlet.http.Cookie;

import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.thrift.TException;

@SuppressWarnings("serial")
@InterceptorRefs({
    @InterceptorRef("myDefault"),
    @InterceptorRef("login")
})

@Results({
    @Result(name="shipping-redirect", type="redirectAction", params = {"actionName" , "shipping"}),
    @Result(name="proceed-to-pay-redirect", type="redirectAction", params = {"actionName" , "proceed-to-pay"}),
        @Result(name="ebs-pay-redirect", type="redirect", location="/ebs-pay/${paymentId}"),
        @Result(name="cod-redirect", type="redirect", location="/pay-success?paymentId=${paymentId}")
})
public class OrderController extends BaseController {
        
        public long getPaymentId() {
                return paymentId;
        }
        
        private static Logger log = Logger.getLogger(Class.class);
        private static final ResourceBundle resource = ResourceBundle.getBundle(OrderController.class.getName());
        private static final String RECAPTCHA_PRIVATE_KEY = resource.getString("recaptcha_private_key");
        
        private String id;
        private long txnId = 0;
        
        private long paymentId;
        
        private String redirectURL;
        
        public OrderController(){
                super();
        }
        
    // GET /order/ orderid
    public String show() {
        log.info("id=" + id);
        htmlSnippets.put("MYACCOUNT_HEADER", pageLoader.getMyaccountHeaderHtml());
        htmlSnippets.put("ORDER_DETAILS", pageLoader.getOrderDetailsHtml(Long.parseLong(id), userinfo.getUserId()));
        return "show";
    }

    // POST /order/
    public String create(){
        String addressIdString = this.request.getParameter("addressid");
        if(addressIdString == null){
                addActionError("Please specify shipping address to continue.");
                return "proceed-to-pay-redirect";
        }
        
        String paymentOption = request.getParameter("payment_option");
        log.info("Payment Option Selected: " + paymentOption);
        if(paymentOption == null || paymentOption.equals("")){
                addActionError("Please select a payment method to continue.");
                return "proceed-to-pay-redirect";
        }
        
        
        long addressId;
        try {
            addressId = Long.parseLong(addressIdString);   
        } catch(NumberFormatException nfe){
            log.error("Unable to get address id", nfe);
            addActionError("Invalid address. Please add an address to the cart.");
            return "shipping-redirect";
        }
         
        long currentCartId = userinfo.getCartId();
        
        if(paymentOption.equals(IPaymentService.COD)){
            if(!verifyCaptcha()){
                addActionError("Invalid captcha");
                return "proceed-to-pay-redirect";    
            }
            
            //Check that this address is eligible for COD shipping.
            UserClient userServiceClient = null;
            try {
                userServiceClient = new UserClient();
                in.shop2020.model.v1.user.UserContextService.Client userClient = userServiceClient.getClient();
                Address address = userClient.getAddressById(addressId);
                
                LogisticsClient logisticsServiceClient = new LogisticsClient();
                if(!logisticsServiceClient.getClient().isCodAllowed(address.getPin())){
                    addActionError("Cash on Delivery is currently not available for this pincode. Please choose a different payment option.");
                    return "proceed-to-pay-redirect";    
                }
            } catch (Exception e) {
                log.error("Unable to talk to the user context service.", e);
                addActionError("We are experiencing some problems. Please try later.");
                return "proceed-to-pay-redirect";
            }
        }
        
        try {
                if(!createOrders(addressId, currentCartId)){
                        addActionError("We are experiencing some problems. Please try later.");
                        return "proceed-to-pay-redirect";
                }
        } catch (Exception e) {
                addActionError("We are experiencing some problems. Please try later.");
                log.error("Exception in createOrders function. Something went wrong.", e);
                return "proceed-to-pay-redirect";
                }
        
        if(paymentOption.equals(IPaymentService.COD)){
            IPaymentService codPaymentService = new CodPaymentService();
            paymentId = codPaymentService.createPayment(userinfo.getCartId(), userinfo.getUserId(), txnId, paymentOption);
            if (paymentId == IPaymentService.PAYMENT_NOT_CREATED) {
                //Very unlikely. The only possible reason can be that the payment service is down.
                log.error("Unable to process the COD payment.");
                addActionError("We are experiencing some problems. Please try later.");
                return "proceed-to-pay-redirect";
            } else {
                CommonPaymentService.processCodTxn(txnId);
                return "cod-redirect";
            }
        } else {
            if(paymentOption.equals(IPaymentService.HDFC_MASTERCARD) || paymentOption.equals(IPaymentService.HDFC_VISA) || paymentOption.equals(IPaymentService.HDFC_VISA_ELECTRON)) {
                // User has selected Visa or MasterCard CC
                IPaymentService hdfcPaymentService = new HdfcPaymentService();
                paymentId = hdfcPaymentService.createPayment(userinfo.getCartId(), userinfo.getUserId(), txnId, paymentOption);
                if (paymentId == IPaymentService.PAYMENT_NOT_CREATED) {
                    log.error("Unable to process payment through HDFC. Falling through to EBS.");
                } else {
                    this.redirectURL = ((HdfcPaymentService)hdfcPaymentService).getRedirectUrl();
                    log.info(this.redirectURL);
                    return "success";
                }
            }

            if(paymentOption.equals(IPaymentService.HDFC_VISA))
                paymentOption = IPaymentService.EBS_VISA;
            else if(paymentOption.equals(IPaymentService.HDFC_MASTERCARD))
                paymentOption = IPaymentService.EBS_MASTERCARD;
            else if(paymentOption.equals(IPaymentService.HDFC_VISA_ELECTRON))
                paymentOption = null;           //Since we don't know the bank's name in this case, we'll let the user select the bank on the EBS page.
            
            IPaymentService ebsPaymentService = new EbsPaymentService();
            paymentId = ebsPaymentService.createPayment(userinfo.getCartId(), userinfo.getUserId(), txnId, paymentOption);
            if(paymentId == IPaymentService.PAYMENT_NOT_CREATED){
                addActionError("We are experiencing some problems. Please try later.");
                return "proceed-to-pay-redirect";
            } else {
                log.info("Successfully created payment for EBS to process. Redirecting to /ebs-pay/" + paymentId);
                return "ebs-pay-redirect";
            }               
        }
            
    }

    /**
     * Verifies if the recaptcha response matches the recaptcha challenge.
     * 
     * @return True if the captcha was valid, false otherwise.
     */
    private boolean verifyCaptcha() {
        String remoteAddr = request.getRemoteAddr();
        ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
        reCaptcha.setPrivateKey(RECAPTCHA_PRIVATE_KEY);

        String challenge = request.getParameter("recaptcha_challenge_field");
        String uresponse = request.getParameter("recaptcha_response_field");
        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);

        log.info("Recaptcha Response:" + reCaptchaResponse.isValid());
        return reCaptchaResponse.isValid();
    }
    
        public String getId(){
                return id;
        }
        
        public void setId(String id){
                this.id = id;
        }
        
        public String getMyaccountHeaderSnippet(){
                return htmlSnippets.get("MYACCOUNT_HEADER");
        }
        
        public String getOrderDetailsSnippet(){
                return htmlSnippets.get("ORDER_DETAILS");
        }
        
        public long getTxn(){
                return this.txnId;
        }

        /**
         * 
         * @param addressId
         * @param currentCartId
         * @return
         */
        private boolean createOrders(long addressId, long currentCartId){
                UserClient userServiceClient = null;
                try {
                        userServiceClient = new UserClient();
                } catch (Exception e) {
                        log.error("Unable to talk to the user context service.", e);
                        return false;
                }
                
                in.shop2020.model.v1.user.UserContextService.Client userClient = userServiceClient.getClient();
                try {
                        userClient.addAddressToCart(currentCartId, addressId);
                } catch (ShoppingCartException e1) {
                        log.error("Not able to set address in the cart.", e1);
                        return false;
                } catch (TException e1) {
                        log.error("Thrift exception while setting address in cart.", e1);
                        return false;
                }
                
                
                try {
                        String errorMsg = userClient.validateCart(currentCartId); 
                        if(!errorMsg.isEmpty()){
                                addActionError(errorMsg);
                                return false;
                        }
                } catch (ShoppingCartException e1) {
                        log.error("Error while validating shopping cart.", e1);
                        return false;
                } catch (TException e) {
                        log.error("Thrift exception while validating cart.", e);
                        return false;
                }
                
                
                try {
                    String sessionSrc = null;
                    Cookie sessionSrcCookie = (Cookie) cookiesMap.get(TrackingInterceptor.SESSION_SRC_COOKIE);
            if (sessionSrcCookie != null) {
                DesEncrypter desEncrypter = new DesEncrypter(TrackingInterceptor.ENCRIPTION_STRING);
                sessionSrc = desEncrypter.decrypt(sessionSrcCookie.getValue());
            }
            
            Cookie sessionSrcTimeCookie = (Cookie) cookiesMap.get(TrackingInterceptor.SESSION_SRC_TIME_COOKIE);
            long sessionTime = 0;
            if (sessionSrcTimeCookie != null) {
                try {
                    sessionTime = Long.parseLong(sessionSrcTimeCookie.getValue());
                } catch (Exception e) {
                    log.warn("Unable to parse session src time cookie.", e);
                }
            }
                    txnId = userClient.createOrders(currentCartId, sessionSrc, sessionTime);
                } catch (ShoppingCartException e1) {
                        log.error("Error while creating orders from cart.", e1);
                        return false;
                } catch (TException e) {
                        log.error("Thrift exception while creating orders from cart.", e);
                        return false;
                }
                
                TransactionClient transactionServiceClient = null;
        try {
            transactionServiceClient = new TransactionClient();
            List<Order> orders = transactionServiceClient.getClient().getOrdersForTransaction(txnId, userinfo.getUserId());
            for (Order order : orders) {
                List<Order> tmpOrders = new ArrayList<Order>();
                tmpOrders.add(order);
                String itemIdString = Utils.getItemIdStringFromOrders(tmpOrders);
                DataLogger.logData(EventType.ORDER_CREATION, getSessionId(), userinfo.getUserId(), userinfo.getEmail(), 
                        Long.toString(order.getId()), Long.toString(currentCartId), itemIdString);
            }
        } catch (Exception e1) {
                log.warn("Unable to log orders through the datalogger", e1);
        }
                
                return true;
        }
        
        public String getRedirectURL(){
                return this.redirectURL;
        }
}