Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.support.controllers;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

import in.shop2020.model.v1.catalog.InventoryServiceException;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.status;
import in.shop2020.support.utils.FileUtils;
import in.shop2020.support.utils.ReportsUtils;
import in.shop2020.thrift.clients.CatalogClient;

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.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
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.util.ServletContextAware;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


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

    private static Logger logger = LoggerFactory.getLogger(StockReportsController.class);    

    private static final int ID = 0, BRAND = 1, MODEL_NUMBER = 2, MODEL_NAME = 3, COLOR = 4, QUANTITY = 5;
    private static final String REPORT_DIR = "/inventory-report";
    
    private HttpSession session;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private ServletContext context;
    
    private String errorMsg = "";
    
    public String index(){
        if(!ReportsUtils.canAccessReport((Long)session.getAttribute(ReportsUtils.ROLE), request.getServletPath())) {
            return "authfail";
        }
        return "index";
    }
    
    public String create(){
        
        Calendar date = new GregorianCalendar();
        int year = date.get(Calendar.YEAR);
        int month = date.get(Calendar.MONTH) +1;
        int day = date.get(Calendar.DAY_OF_MONTH);
        String filename = "inventory-report." + year + "-" + month + "-" + day + ".xls";
        
        File inventoryReportFile = new File(REPORT_DIR + File.separator + filename);
        
        if(!inventoryReportFile.exists()){
            //Report doesn't exist. Need to generate it.
            ByteArrayOutputStream baosXLS = generateInventoryStockReport();
            if (baosXLS == null) {
                errorMsg = "Could not get output";
                return "index";
            }
            
            try {
                FileOutputStream f = new FileOutputStream(inventoryReportFile);
                baosXLS.writeTo(f);
                f.close();
            } catch (FileNotFoundException e) {
                logger.error("Error while writing the inventory report", e);
                return "index";
            } catch (IOException e) {
                logger.error("Error while writing the inventory report", e);
                return "index";
            }
        }
        
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "inline; filename=" + filename);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            baos.write(FileUtils.getBytesFromFile(new File(REPORT_DIR + File.separator + filename)));
            ServletOutputStream sos = response.getOutputStream();
            baos.writeTo(sos);
            sos.flush();
            errorMsg = "Report generated";
        } catch (IOException e) {
            logger.error("Unable to stream the inventory stock report", e);
            errorMsg = "Failed to write to response.";
        }
        return "index";
    }
    
    private ByteArrayOutputStream generateInventoryStockReport(){
        List<RowItem> outOfStockItems = new ArrayList<RowItem>();
        List<RowItem> itemsDeliverableNextDay = new ArrayList<RowItem>();
        List<RowItem> itemsNotDeliverableNextDay = new ArrayList<RowItem>();
        
        CatalogClient catalogClientService;
        try {
            catalogClientService = new CatalogClient();
            in.shop2020.model.v1.catalog.InventoryService.Client client = catalogClientService.getClient();
            List<Item> items = client.getAllItems(false);

            for(Item item : items){
                if(!"Handsets".equals(item.getProductGroup()))
                    continue;
                status state = item.getItemStatus();
                switch(state){
                case IN_PROCESS:
                case CONTENT_COMPLETE:
                case DELETED:
                case PHASED_OUT:
                    continue;
                case PAUSED:
                case PAUSED_BY_RISK:
                case ACTIVE:
                    RowItem rowItem = new RowItem(item);
                    if(state == status.ACTIVE){
                        if(rowItem.quantity >= 2)
                            itemsDeliverableNextDay.add(rowItem);
                        else
                            itemsNotDeliverableNextDay.add(rowItem);    
                    }else
                        outOfStockItems.add(rowItem);
                }
            }
        } catch (TTransportException e) {
            logger.error("Unable to get the items from the inventory", e);
            return null;
        } catch (InventoryServiceException e) {
            logger.error("Error while getting the items from the inventory", e);
            return null;
        } catch (TException e) {
            logger.error("Error while getting the items from the inventory", e);
            return null;
        }
        
        ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();

        Workbook wb = new HSSFWorkbook();
        
        createSheet(wb, "Items Deliverable on Next Day", itemsDeliverableNextDay);
        createSheet(wb, "Items Not Deliverable on Next Day", itemsNotDeliverableNextDay);
        createSheet(wb, "Out of Stock Items", outOfStockItems);
        
        try {
            wb.write(baosXLS);
            baosXLS.close();
        } catch (IOException e) {
            logger.error("Error while streaming inventory stock report", e);
            return null;
        }
        return baosXLS;
    }
    
    private void createSheet(Workbook wb, String name, List<RowItem> items){
        Sheet sheet = wb.createSheet(name);
        short serialNo = 0;
        Row headerRow = sheet.createRow(serialNo++);
        headerRow.createCell(ID).setCellValue("Item Id");
        headerRow.createCell(BRAND).setCellValue("Brand");
        headerRow.createCell(MODEL_NUMBER).setCellValue("Model Number");
        headerRow.createCell(MODEL_NAME).setCellValue("Model Name");
        headerRow.createCell(COLOR).setCellValue("Color");
        headerRow.createCell(QUANTITY).setCellValue("Quantity");
        
        for(RowItem item : items){
            Row contentRow = sheet.createRow(serialNo++);
            contentRow.createCell(ID).setCellValue(item.id);
            contentRow.createCell(BRAND).setCellValue(item.brand);
            contentRow.createCell(MODEL_NUMBER).setCellValue(item.modelNumber);
            contentRow.createCell(MODEL_NAME).setCellValue(item.modelName);
            contentRow.createCell(COLOR).setCellValue(item.color);
            contentRow.createCell(QUANTITY).setCellValue(item.quantity);
        }
    }
    
    public String getErrorMsg() {
        return errorMsg;
    }

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

    @Override
    public void setServletResponse(HttpServletResponse res) {
        this.response = res;
    }
    
    @Override
    public void setServletContext(ServletContext context) {
        this.context = context;
    }

    public String getServletContextPath() {
        return context.getContextPath();
    }
    
    public static void main(String[] args) {
        StockReportsController src = new StockReportsController();
        try {
            String userHome = System.getProperty("user.home");
            FileOutputStream f = new FileOutputStream(userHome + "/stock-report.xls");
            ByteArrayOutputStream baosXLS = src.generateInventoryStockReport();
            baosXLS.writeTo(f);
            f.close();
        } catch (FileNotFoundException e) {
            logger.error("Error creating inventory stock report", e);
        } catch (IOException e) {
            logger.error("IO error while creating inventory stock report", e);
        }
        System.out.println("Successfully generated the inventory stock report");
    }
    
    class RowItem {
        public long id;
        public String brand;
        public String modelNumber;
        public String modelName;
        public String color;
        public long quantity;
        
        public RowItem(Item item){
           id = item.getId();
           brand = item.getBrand();
           modelNumber = item.getModelNumber();
           modelName = item.getModelName();
           color = item.getColor();
           quantity = 0;
           for(Map.Entry<Long, Long> entry : item.getItemInventory().getAvailability().entrySet()){
               quantity += entry.getValue();
           }
        }
    }
}