Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.support.controllers;

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.TransactionServiceException;
import in.shop2020.model.v1.user.Affiliate;
import in.shop2020.model.v1.user.MasterAffiliate;
import in.shop2020.model.v1.user.TrackLog;
import in.shop2020.model.v1.user.UserAffiliateException;
import in.shop2020.model.v1.user.UserContextService.Client;
import in.shop2020.payments.Payment;
import in.shop2020.payments.PaymentException;
import in.shop2020.support.utils.ReportsUtils;
import in.shop2020.thrift.clients.PaymentClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.UserClient;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides reports about successful registrations and orders place through an
 * affiliate.
 * 
 * @author Vikas Malik
 * 
 */
@InterceptorRefs({
    @InterceptorRef("defaultStack"),
    @InterceptorRef("login")
})
public class AffiliateController implements ServletRequestAware, ServletResponseAware{

    private static Logger log = LoggerFactory.getLogger(AffiliateController.class);
    
        private HttpServletResponse response;
        private HttpServletRequest request;
        private HttpSession session;
    
        private String errorMsg = "";
        private List<MasterAffiliate> masterAffiliates;
        
        @Override
        public void setServletResponse(HttpServletResponse res) {
                this.response = res;
        }

        @Override
    public void setServletRequest(HttpServletRequest req) {
            this.request = req;
        this.session = req.getSession();
    }
        
        public String index()  {
            log.info(request.getServletPath());
        if (!ReportsUtils.canAccessReport(
                (Long) session.getAttribute(ReportsUtils.ROLE),
                request.getServletPath())) 
        {
            return "exception";
        }
        try {
                UserClient userContextServiceClient = new UserClient();
            Client userClient = userContextServiceClient.getClient();
            masterAffiliates = userClient.getAllMasterAffiliates();
        } catch (Exception e) {
            log.error("Error while getting all affiliates", e);
        }
        return "report";
    }
        
        public String create()  {
            try   {
                long mAfId = Long.parseLong(request.getParameter("masterAffiliate"));
                String filename;
                String startDateStr = request.getParameter("startDate");
                String endDateStr = request.getParameter("endDate");
                
                DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
                Date startDate = null, endDate = null;
                try {
                    startDate = df.parse(startDateStr);
                    endDate = df.parse(endDateStr);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(endDate);
                    cal.add(Calendar.DATE, 1);
                    endDate.setTime(cal.getTimeInMillis());
                } catch (ParseException pe) {
                    errorMsg = "Please enter start and end dates in format MM/dd/yyyy";
                    return "report";
                }
                
                UserClient userContextServiceClient = new UserClient();
            PaymentClient paymentServiceClient = new PaymentClient();
            TransactionClient transactionServiceClient = new TransactionClient();
            
            Client userClient = userContextServiceClient.getClient();
            in.shop2020.payments.PaymentService.Client paymentClient = paymentServiceClient.getClient();
            
            Set<Long> Payments = new HashSet<Long>();
            List<Map<String, String>> contentRows = new LinkedList<Map<String,String>>();
            List<Affiliate> affiliates;
            if (mAfId == -1) {
                filename = "All";
                affiliates = new ArrayList<Affiliate>();
                for(MasterAffiliate mAffiliate : userClient.getAllMasterAffiliates()) {
                    affiliates.addAll(userClient.getAffiliatesByMasterAffiliate(mAffiliate.getId()));
                }
            }
            else {
                affiliates = userClient.getAffiliatesByMasterAffiliate(mAfId);
                filename = userClient.getMasterAffiliateById(mAfId).getName();
            }
            
            for (Affiliate aff : affiliates) {
                MasterAffiliate mAffiliate = userClient.getMasterAffiliateById(aff.getMasterAffiliateId());
                for (TrackLog tracklog : userClient.getTrackLogsByAffiliate(aff.getId(), startDate.getTime(), endDate.getTime())) {
                    boolean orderCompleted = false;
                    Map<String, String> contentRow = new HashMap<String, String>();
                    contentRow.put("mAffiliate", mAffiliate.getName());
                    contentRow.put("affiliate", aff.getName());
                    contentRow.put("affiliateUrl", aff.getUrl());
                    contentRow.put("date",String.valueOf(tracklog.getAddedOn()));
                    contentRow.put("event", tracklog.getEvent());
                    contentRow.put("url", tracklog.getUrl());
                    if (tracklog.getEvent().equals("payment success")) {
                        try {
                            long paymentId = Long.parseLong(tracklog.getData().replaceAll("\\(*\\)", ""));
                            if (Payments.contains(paymentId)) {
                                continue;
                            }
                            Payments.add(paymentId);
                            Payment payment = paymentClient.getPayment(paymentId);
                            List<Order> orders = transactionServiceClient.getClient().getOrdersForTransaction(
                                            payment.getMerchantTxnId(),
                                            payment.getUserId());
                            contentRow.put("amount", Double.toString(payment.getAmount()));
                            String itemString = "";
                            for (Order order : orders) {
                                if (order.getStatus() == OrderStatus.DELIVERY_SUCCESS) {
                                    orderCompleted = true;
                                }
                                List<LineItem> items = order.getLineitems();
                                for (LineItem item : items) {
                                    itemString += item.getBrand() + " "
                                            + item.getModel_name() + " "
                                            + item.getModel_number() + "("
                                            + item.getQuantity() + ", "
                                            + item.getTotal_price() + "), ";
                                }
                                contentRow.put("items", itemString.replaceAll("null", ""));
                            }
                        } catch (PaymentException e) {
                            log.error("Error while getting payment info", e);
                        } catch (TransactionServiceException e) {
                            log.error("Error while getting order info", e);
                        } catch (TException e) {
                            log.error("Unable to get order or payment info", e);
                        } catch (NullPointerException e) {
                            log.error("Unexpected exception", e);
                        }
                    }
                    contentRow.put("data", tracklog.getData());
                    if (orderCompleted) {
                        contentRows.add(contentRow);
                    }
                }
            }
             
            // Preparing XLS file for output
            response.setContentType("application/vnd.ms-excel");
            
            response.setHeader("Content-disposition", "inline; filename=" + filename + "-affiliate-report" + ".xls");
            
            ServletOutputStream sos;
            try {
                ByteArrayOutputStream baos = getSpreadSheetData(contentRows);
                sos = response.getOutputStream();
                baos.writeTo(sos);
                sos.flush();
            } catch (IOException e) {
                log.error("Unable to stream the affiliates report", e);
                errorMsg = "Failed to write to response.";
            }
        } catch (UserAffiliateException e) {
            log.error("Error while getting affiliated users", e);
            errorMsg = e.getMessage();
        } catch (TException e) {
            log.error("Unable to get affiliated users", e);
            errorMsg = e.getMessage();
        } catch (Exception e) {
            log.error("Unexpected exception", e);
            errorMsg = e.getMessage();
        }
        return null;
        }
        
        // Prepares the XLS worksheet object and fills in the data with proper formatting
        private ByteArrayOutputStream getSpreadSheetData(List<Map<String, String>> contentRows)
        {
            ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();

                Workbook wb = new HSSFWorkbook();
            
            Font font = wb.createFont();
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
            CellStyle style = wb.createCellStyle();
            style.setFont(font);
            
            CreationHelper createHelper = wb.getCreationHelper();
            CellStyle dateCellStyle = wb.createCellStyle();
            dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("DD/MM/YYYY HH:MM"));
            
            createAffiliateSheet(contentRows, wb, style, dateCellStyle);
                        
                // Write the workbook to the output stream
                try {
                        wb.write(baosXLS);
                        baosXLS.close();
                } catch (IOException e) {
                        log.error("Unable to get the byte array for the affiliate report", e);
                }               
                return baosXLS;
        }
        
        private void createAffiliateSheet(List<Map<String, String>> contentRows, Workbook wb, CellStyle style, CellStyle dateCellStyle) 
        {
                // Affiliate SHEET
            Sheet affSheet = wb.createSheet("Affiliates Report");
            short affSerialNo = 0;

            Row affTitleRow = affSheet.createRow(affSerialNo ++);
            Cell affTitleCell = affTitleRow.createCell(0);
            affTitleCell.setCellValue("Affiliates Report");
            affTitleCell.setCellStyle(style);
            
            affSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
            
            affSheet.createRow(affSerialNo ++);
                
            Row affHeaderRow = affSheet.createRow(affSerialNo++);
            affHeaderRow.createCell(0).setCellValue("Affiliate");
            affHeaderRow.createCell(1).setCellValue("Affiliate Url");
            affHeaderRow.createCell(2).setCellValue("Date");
            affHeaderRow.createCell(3).setCellValue("Event");
            affHeaderRow.createCell(4).setCellValue("Url");
            affHeaderRow.createCell(5).setCellValue("Data");
            affHeaderRow.createCell(6).setCellValue("Items");
            affHeaderRow.createCell(7).setCellValue("Amount");
            for (int i=0; i<8 ;i++) {
                affHeaderRow.getCell(i).setCellStyle(style);
            }
            
                for( Map<String, String> contentRow : contentRows) {
                        affSerialNo++;
                        Row commContentRow = affSheet.createRow(affSerialNo);
                        
                        commContentRow.createCell(0).setCellValue(contentRow.get("affiliate"));
                        commContentRow.createCell(1).setCellValue(contentRow.get("affiliateUrl"));
                        commContentRow.createCell(2).setCellValue(new Date(Long.parseLong(contentRow.get("date"))));
                        commContentRow.getCell(2).setCellStyle(dateCellStyle);
            commContentRow.createCell(3).setCellValue(contentRow.get("event"));
                        commContentRow.createCell(4).setCellValue(contentRow.get("url"));
                        commContentRow.createCell(5).setCellValue(contentRow.get("data"));
                        if (contentRow.containsKey("items")) {
                            commContentRow.createCell(6).setCellValue(contentRow.get("items"));
                        }
                        if (contentRow.containsKey("amount")) {
                    commContentRow.createCell(7).setCellValue(contentRow.get("amount"));
                        }
                }
        for (int i = 0; i<8; i++) {
            affSheet.autoSizeColumn(i);
        }
        }

        public String getErrorMsg() {
                return errorMsg;
        }
        
        public List<MasterAffiliate> getMasterAffiliates() {
        return masterAffiliates;
    }
}