Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.support.controllers;

import in.shop2020.model.v1.inventory.InventoryServiceException;
import in.shop2020.model.v1.inventory.Warehouse;
import in.shop2020.model.v1.order.LineItem;
import in.shop2020.model.v1.order.Order;
import in.shop2020.model.v1.order.ReturnOrder;
import in.shop2020.model.v1.order.TransactionServiceException;
import in.shop2020.thrift.clients.InventoryClient;
import in.shop2020.thrift.clients.TransactionClient;

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.Date;
import java.util.List;

import javax.servlet.ServletContext;
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.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.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.apache.struts2.util.ServletContextAware;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author Varun Gupta
 * @version 1.0
 * @description HotspotReconciliationController handles requests to generate a reconciliation
 * report in XLS format for all the transactions with HotSpot within a given date range.
 * 
 */

@InterceptorRefs({
    @InterceptorRef("defaultStack"),
    @InterceptorRef("login")
})
@Results({
    @Result(name="authfail", type="redirectAction", params = {"actionName" , "reports"})
})
public class HotspotReconciliationController implements ServletResponseAware, ServletRequestAware, ServletContextAware {

    private static Logger logger = LoggerFactory.getLogger(HotspotReconciliationController.class);
    
        private enum OrderReportColumn {
            ORDER_ID(0),
                BILLING_NUMBER(1),
                BILLING_DATE(2),
                CUSTOMER_NAME(3),
                BRAND(4),
                MODEL_NAME(5),
                MODEL_NUMBER(6),
                COLOR(7),
                XFER_PRICE(8),
                SELLING_PRICE(9),
                DELIVERY_DATE(10),
                STATUS(11);
                
                private int value;
                
                OrderReportColumn(int value) {
                        this.value = value;
                }
                public int getValue(){
                        return this.value;
                }
        }
        
        private enum ReturnOrderReportColumn {
                ORDER_ID(0),
                WAREHOUSE_ID(1),
                INVOICE_NUMBER(2),
                PRODUCT_GROUP(3),
                BRAND(4),
                MODEL_NUMBER(5),
                COLOR(6),
                CREATED_ON(7),
                XFER_PRICE(8);
                
                private int value;
                
                ReturnOrderReportColumn(int value) {
                        this.value = value;
                }
                public int getValue(){
                        return this.value;
                }
        }
        
        //FIXME: Read this configuration from the config server
        //private String hotspotReconciliationReportPath = "/HotspotReports";
        
        private HttpServletRequest request;
        private HttpServletResponse response;
    private HttpSession session;
    private ServletContext context;
        private String id;
        
        private final DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
        
        public HotspotReconciliationController(){
                
        }
        
        public String index() {
//          if(!ReportsUtils.canAccessReport((Long)session.getAttribute(ReportsUtils.ROLE), request.getServletPath())) {
//              return "authfail";
//          }
            return "report";
        }
        
        // Handles the POST request (Form Submission)
        public HttpHeaders create(){
                DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
                
                try     {
                        //Formatting Form input parameters
                    Date startDate = dateFormat.parse(request.getParameter("start"));
                    Date endDate = dateFormat.parse(request.getParameter("end"));
                        
                        InventoryClient csc = new InventoryClient();
                        in.shop2020.model.v1.inventory.InventoryService.Client catalogClient = csc.getClient();
                        List<Warehouse> warehouses = catalogClient.getAllWarehouses(true);

                        TransactionClient transactionServiceClient = new TransactionClient();
                        in.shop2020.model.v1.order.TransactionService.Client client = transactionServiceClient.getClient();
                        
                        List<Order> orders = new ArrayList<Order>();
                        List<ReturnOrder> returnOrders = new ArrayList<ReturnOrder>();

                        //Retrieving all the orders across all the warehouses
                        long fromTime = startDate.getTime();
                        long toTime = endDate.getTime();
                        for(Warehouse warehouse : warehouses)   {
                                orders.addAll(client.getOrdersByBillingDate(null, fromTime, toTime, warehouse.getId()));
                                returnOrders.addAll(client.getReturnOrders(warehouse.getId(), fromTime, toTime));
                        }
                        logger.debug("Total number of Orders: " + orders.size());
                        
                        // Preparing XLS file for output
                        response.setContentType("application/vnd.ms-excel");
                        
                        DateFormat dateFormatForFile = new SimpleDateFormat("dd.MM.yyyy");
                        response.setHeader("Content-disposition", "inline; filename=hotspot-reconciliation-from-" + dateFormatForFile.format(startDate) + "-" + dateFormatForFile.format(endDate) + ".xls");
                        
                        ServletOutputStream sos;
                        try {
                                ByteArrayOutputStream baos = getReconciliationReport(orders, returnOrders, startDate, endDate);
                                sos = response.getOutputStream();
                                baos.writeTo(sos);
                                sos.flush();
                        } catch (IOException e) {
                                logger.error("Error while streaming the hotspot reconciliation report", e);
                        }

                } catch (ParseException e)      {
                        logger.error("Unable to parse the start or end date", e);
                } catch (TransactionServiceException e) {
                        logger.error("Error while getting order information from the transaction service", e);
                } catch (InventoryServiceException e) {
                    logger.error("Error while getting the list of warehouses from the catalog service", e);
        } catch (TException e) {
            logger.error("Unable to get the orders or the warehouses", e);
        } catch (Exception e)   {
            logger.error("Unexpected exception", e);
        }
                return new DefaultHttpHeaders("report1");
        }
        
        // Prepares the XLS worksheet object and fills in the data with proper formatting
        private ByteArrayOutputStream getReconciliationReport(List<Order> orders, List<ReturnOrder> returnOrders, Date startDate, Date endDate) {
                ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();

            Workbook wb = new HSSFWorkbook();       

            //Create the style for the title row
            Font font = wb.createFont();
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
            CellStyle boldStyle = wb.createCellStyle();
            boldStyle.setFont(font);
            
            CellStyle rightAlignStyle = wb.createCellStyle();
            rightAlignStyle.setAlignment(CellStyle.ALIGN_RIGHT);
            
                Sheet orderSheet = wb.createSheet("Orders");
                Sheet returnSheet = wb.createSheet("Returns");
                
            populateOrderSheet(orders, startDate, endDate, orderSheet, boldStyle, rightAlignStyle);
            populateReturnOrderSheet(returnOrders, startDate, endDate, returnSheet, boldStyle, rightAlignStyle);
        
                // Write the workbook to the output stream
                try {
                        wb.write(baosXLS);
                        baosXLS.close();
                } catch (IOException e) {
                        logger.error("Unable to write the hotspot reconciliation report to the byte array", e);
                }               
                return baosXLS;
        }

        private void populateOrderSheet(List<Order> orders, Date startDate, Date endDate, Sheet sheet, CellStyle style, CellStyle rightAlignStyle) {
            short serialNo = 0;
            
            // Create the title row and put all the titles in it. Rows are 0 based.
            Row titleRow = sheet.createRow(serialNo ++);
            Cell titleCell = titleRow.createCell(0);
            titleCell.setCellValue("Order Reconciliation Report (" + DATE_FORMAT.format(startDate) + " - " + DATE_FORMAT.format(endDate) + ")");
            titleCell.setCellStyle(style);
            
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
            
            sheet.createRow(serialNo ++);
            
            Row headerRow = sheet.createRow(serialNo ++);
            headerRow.createCell(OrderReportColumn.ORDER_ID.getValue()).setCellValue("Order Id");
            headerRow.createCell(OrderReportColumn.BILLING_NUMBER.getValue()).setCellValue("Billing Number");
            headerRow.createCell(OrderReportColumn.BILLING_DATE.getValue()).setCellValue("Billing Date");
            headerRow.createCell(OrderReportColumn.CUSTOMER_NAME.getValue()).setCellValue("Customer Name");
            headerRow.createCell(OrderReportColumn.BRAND.getValue()).setCellValue("Brand");
            headerRow.createCell(OrderReportColumn.MODEL_NAME.getValue()).setCellValue("Model Name");
            headerRow.createCell(OrderReportColumn.MODEL_NUMBER.getValue()).setCellValue("Model Number");
            headerRow.createCell(OrderReportColumn.COLOR.getValue()).setCellValue("Color");
            headerRow.createCell(OrderReportColumn.XFER_PRICE.getValue()).setCellValue("Transfer Price");
            headerRow.createCell(OrderReportColumn.SELLING_PRICE.getValue()).setCellValue("Selling Price");
            headerRow.createCell(OrderReportColumn.DELIVERY_DATE.getValue()).setCellValue("Delivery Date");
            headerRow.createCell(OrderReportColumn.STATUS.getValue()).setCellValue("Current Status");

            sheet.createRow(serialNo ++);
            double totalTransferPrice = 0.0;
            double totalSellingPrice = 0.0;
            
            for(Order order : orders)   {
                Row contentRow = sheet.createRow(serialNo++);
                    
                    LineItem lineItem = order.getLineitems().get(0);
                    double transferPrice = lineItem.getTransfer_price();
                    totalTransferPrice += transferPrice;

            double sellingPrice = lineItem.getTotal_price();
            totalSellingPrice += sellingPrice;

            contentRow.createCell(OrderReportColumn.ORDER_ID.getValue()).setCellValue(order.getId());
                    contentRow.createCell(OrderReportColumn.BILLING_NUMBER.getValue()).setCellValue(order.getInvoice_number());
                    contentRow.createCell(OrderReportColumn.BILLING_DATE.getValue()).setCellValue(DATE_FORMAT.format(new Date(order.getBilling_timestamp())));
                    contentRow.createCell(OrderReportColumn.CUSTOMER_NAME.getValue()).setCellValue(order.getCustomer_name());
                    contentRow.createCell(OrderReportColumn.BRAND.getValue()).setCellValue(getValueForEmptyString(lineItem.getBrand()));
                    contentRow.createCell(OrderReportColumn.MODEL_NAME.getValue()).setCellValue(getValueForEmptyString(lineItem.getModel_name()));
                    contentRow.createCell(OrderReportColumn.MODEL_NUMBER.getValue()).setCellValue(getValueForEmptyString(lineItem.getModel_number()));
                    contentRow.createCell(OrderReportColumn.COLOR.getValue()).setCellValue(getValueForEmptyString(lineItem.getColor()));
                    contentRow.createCell(OrderReportColumn.XFER_PRICE.getValue()).setCellValue(transferPrice);
                    contentRow.createCell(OrderReportColumn.SELLING_PRICE.getValue()).setCellValue(sellingPrice);
                    
                    if(order.getDelivery_timestamp() > 0)       {
                        contentRow.createCell(OrderReportColumn.DELIVERY_DATE.getValue()).setCellValue(DATE_FORMAT.format(new Date(order.getDelivery_timestamp())));
                    } else      {
                        contentRow.createCell(OrderReportColumn.DELIVERY_DATE.getValue()).setCellValue("-");
                    }
                    contentRow.createCell(OrderReportColumn.STATUS.getValue()).setCellValue(order.getStatus().name());
            }
            sheet.createRow(serialNo ++);
        Row contentRow = sheet.createRow(serialNo);
        contentRow.createCell(0).setCellValue("Total Transfer Price");
        contentRow.createCell(OrderReportColumn.XFER_PRICE.getValue()).setCellValue(totalTransferPrice);
        contentRow.createCell(OrderReportColumn.SELLING_PRICE.getValue()).setCellValue(totalSellingPrice);
        sheet.addMergedRegion(new CellRangeAddress(serialNo, serialNo, 0, 5));
        }

        private void populateReturnOrderSheet(List<ReturnOrder> returnOrders, Date startDate, Date endDate, Sheet sheet, CellStyle titleStyle, CellStyle rightAlignStyle) {
            short serialNo = 0;
            
            // Create the title row and put all the titles in it. Rows are 0 based.
            Row titleRow = sheet.createRow(serialNo ++);
            Cell titleCell = titleRow.createCell(0);
            titleCell.setCellValue("Return Orders Reconciliation Report (" + DATE_FORMAT.format(startDate) + " - " + DATE_FORMAT.format(endDate) + ")");
            titleCell.setCellStyle(titleStyle);
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
            
            // Create the header row
            sheet.createRow(serialNo ++);           
            Row headerRow = sheet.createRow(serialNo ++);
            headerRow.createCell(ReturnOrderReportColumn.ORDER_ID.getValue()).setCellValue("Order Id");
            headerRow.createCell(ReturnOrderReportColumn.WAREHOUSE_ID.getValue()).setCellValue("Warehouse Id");
            headerRow.createCell(ReturnOrderReportColumn.INVOICE_NUMBER.getValue()).setCellValue("Invoice Number");
            headerRow.createCell(ReturnOrderReportColumn.PRODUCT_GROUP.getValue()).setCellValue("Product Group");
            headerRow.createCell(ReturnOrderReportColumn.BRAND.getValue()).setCellValue("Brand");
            headerRow.createCell(ReturnOrderReportColumn.MODEL_NUMBER.getValue()).setCellValue("Model Number");
            headerRow.createCell(ReturnOrderReportColumn.COLOR.getValue()).setCellValue("Color");
            headerRow.createCell(ReturnOrderReportColumn.CREATED_ON.getValue()).setCellValue("Created On");
            headerRow.createCell(ReturnOrderReportColumn.XFER_PRICE.getValue()).setCellValue("Transfer Price");
            

            // Create an empty row
            sheet.createRow(serialNo ++);
            
            double totalTransferPrice = 0.0;
            for(ReturnOrder order : returnOrders)       {
                Row contentRow = sheet.createRow(serialNo++);
                    double transferPrice = order.getTransferPrice();
                    totalTransferPrice += transferPrice;

            contentRow.createCell(ReturnOrderReportColumn.ORDER_ID.getValue()).setCellValue(order.getOrderId());
            contentRow.createCell(ReturnOrderReportColumn.WAREHOUSE_ID.getValue()).setCellValue(order.getWarehouseId());
            contentRow.createCell(ReturnOrderReportColumn.INVOICE_NUMBER.getValue()).setCellValue(order.getInvoiceNumber());
            contentRow.createCell(ReturnOrderReportColumn.PRODUCT_GROUP.getValue()).setCellValue(order.getProductGroup());
            contentRow.createCell(ReturnOrderReportColumn.BRAND.getValue()).setCellValue(order.getBrand());
            contentRow.createCell(ReturnOrderReportColumn.MODEL_NUMBER.getValue()).setCellValue(order.getModelNumber());
            contentRow.createCell(ReturnOrderReportColumn.COLOR.getValue()).setCellValue(order.getColor());
            contentRow.createCell(ReturnOrderReportColumn.CREATED_ON.getValue()).setCellValue(DATE_FORMAT.format(new Date(order.getCreatedAt())));
            contentRow.createCell(ReturnOrderReportColumn.XFER_PRICE.getValue()).setCellValue(transferPrice);
            }
            sheet.createRow(serialNo ++);
        Row contentRow = sheet.createRow(serialNo);
        Cell totalCell = contentRow.createCell(0);
        totalCell.setCellValue("Total Transfer Price");
        totalCell.setCellStyle(rightAlignStyle);
        
        contentRow.createCell(ReturnOrderReportColumn.XFER_PRICE.getValue()).setCellValue(totalTransferPrice);
        sheet.addMergedRegion(new CellRangeAddress(serialNo, serialNo, 0, ReturnOrderReportColumn.CREATED_ON.getValue()));
        }
        
        public String getId(){
                return id;
        }
        
        public void setId(String id){
                this.id = id;
        }

        @Override
        public void setServletRequest(HttpServletRequest request) {
                this.request = request;
                this.session = request.getSession();    
        }

        @Override
        public void setServletResponse(HttpServletResponse response) {
                this.response  = response;
        }
        
        private String getValueForEmptyString(String s){
                if(s==null || s.equals(""))
                        return "-";
                else
                        return s; 
        }
        @Override
    public void setServletContext(ServletContext context) {
        this.context = context;
    }

    public String getServletContextPath() {
        return context.getContextPath();
    }
}