Rev 5931 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package in.shop2020.support.controllers;import in.shop2020.logistics.DeliveryType;import in.shop2020.logistics.LogisticsService.Client;import in.shop2020.logistics.LogisticsServiceException;import in.shop2020.model.v1.catalog.CatalogServiceException;import in.shop2020.model.v1.catalog.Item;import in.shop2020.model.v1.catalog.status;import in.shop2020.model.v1.inventory.InventoryServiceException;import in.shop2020.model.v1.inventory.ItemInventory;import in.shop2020.support.utils.FileUtils;import in.shop2020.support.utils.ReportsUtils;import in.shop2020.thrift.clients.CatalogClient;import in.shop2020.thrift.clients.InventoryClient;import in.shop2020.thrift.clients.LogisticsClient;import in.shop2020.utils.CategoryManager;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.HashMap;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;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.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 String REPORT_DIR = "/inventory-report";private static final String DEFAULT_PINCODE = "110001";private static final long REPORT_GENERATION_INTERVAL = 3;private static final long CUT_OFF_TIME = 15;private static long NEXT_DAY_DELAY = 1;private static final int ID = 0, BRAND = 1, MODEL_NUMBER = 2, MODEL_NAME = 3, COLOR = 4, DELIVERY_DAYS = 5, TOTAL_AVAILABILITY = 6, TOTAL_RESERVED = 7;private static final int WH1_AVAILABILITY = 8, WH1_RESERVED = 9, WH5_AVALABILITY = 10, WH5_RESERVED = 11, WH7_AVALABILITY = 12, WH7_RESERVED = 13, RISKY = 14, EXPECTED_DELAY = 15, STICKY = 16, SIMILAR_ITEMS = 17;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() throws NumberFormatException, IOException{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);int hour = date.get(Calendar.HOUR_OF_DAY);long currentTimestamp = date.getTimeInMillis();String lastTimestampString = org.apache.commons.io.FileUtils.readFileToString(new File(REPORT_DIR + File.separator + "last.timestamp"));lastTimestampString = lastTimestampString.replace("\"", "").replace("\n", "");long lastTimestamp = Long.parseLong(lastTimestampString);String filename = "inventory-report." + year + "-" + month + "-" + day + "-" + lastTimestamp + ".xls";if(hour >= CUT_OFF_TIME){NEXT_DAY_DELAY = 2;}else{NEXT_DAY_DELAY = 1;}if(currentTimestamp - lastTimestamp > REPORT_GENERATION_INTERVAL*60*60*1000){filename = "inventory-report." + year + "-" + month + "-" + day + "-" + currentTimestamp + ".xls";File inventoryReportFile = new File(REPORT_DIR + File.separator + filename);ByteArrayOutputStream baosXLS = generateInventoryStockReport();if (baosXLS == null) {errorMsg = "Could not get output";return "index";}try {FileOutputStream f = new FileOutputStream(inventoryReportFile);baosXLS.writeTo(f);f.close();org.apache.commons.io.FileUtils.writeStringToFile(new File(REPORT_DIR + File.separator + "last.timestamp"), currentTimestamp+"");} 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(){Map<String, Map<String, List<RowItem>>> categoryWiseStock = new LinkedHashMap<String, Map<String, List<RowItem>>>();String nextDay = "Deliverable on Next Day";String notNextDay = "Not Deliverable on Next Day";String notAvailable = "Out of Stock";LogisticsClient logisticsServiceClient;CatalogClient catalogClientService;try {catalogClientService = new CatalogClient();InventoryClient inventoryClientService = new InventoryClient();logisticsServiceClient = new LogisticsClient();in.shop2020.model.v1.catalog.CatalogService.Client client = catalogClientService.getClient();in.shop2020.model.v1.inventory.InventoryService.Client iclient = inventoryClientService.getClient();List<Item> items = client.getAllItems(false);Client logisticsClient = logisticsServiceClient.getClient();CategoryManager catm = CategoryManager.getCategoryManager();for(Item item : items){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:if(item.getCategory() == -1 || item.getCategory() == 0){continue;}String category = catm.getCategory(catm.getCategory(item.getCategory()).getParent_category_id()).getLabel();Map<String, List<RowItem>> sheetsMap = categoryWiseStock.get(category);if(sheetsMap == null){sheetsMap = new HashMap<String, List<RowItem>>();categoryWiseStock.put(category, sheetsMap);sheetsMap.put(nextDay, new ArrayList<RowItem>());sheetsMap.put(notNextDay, new ArrayList<RowItem>());sheetsMap.put(notAvailable, new ArrayList<RowItem>());}long deliveryDays = 3;try{deliveryDays = logisticsClient.getLogisticsEstimation(item.getId(), DEFAULT_PINCODE, DeliveryType.PREPAID).getDeliveryTime();}catch (LogisticsServiceException e) {logger.error("Error while getting estimate of the inventory for item " + item.getId(), e);}ItemInventory inventory = iclient.getItemInventoryByItemId(item.getId());RowItem rowItem = new RowItem(item, deliveryDays, inventory);if(state == status.ACTIVE){if(deliveryDays == NEXT_DAY_DELAY)sheetsMap.get(nextDay).add(rowItem);elsesheetsMap.get(notNextDay).add(rowItem);}else{sheetsMap.get(notAvailable).add(rowItem);List<Item> similaritems= client.getAllSimilarItems(item.getId());if(similaritems!=null){boolean isFirst = true;for(Item item1: similaritems){if(isFirst){isFirst = false;}else{rowItem.similarItems += "\n";}rowItem.similarItems += item1.getBrand() + " " + item1.getModelName() + " " + item1.getModelNumber() + " " + item1.getColor();}}}}}} catch (TTransportException e) {logger.error("Unable to get the items from the inventory", e);return null;} catch (CatalogServiceException 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;} catch (InventoryServiceException e) {logger.error("Error while getting the items from the inventory", e);return null;}ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();Workbook wb = new HSSFWorkbook();// for(String category: categoryWiseStock.keySet()){// Map<String, List<RowItem>> value = categoryWiseStock.get(category);// createSheet(wb, category + " - " + nextDay, value.get(nextDay));// createSheet(wb, category + " - " + notNextDay, value.get(notNextDay));// createSheet(wb, category + " - " + notAvailable, value.get(notAvailable));// }//Hardcoding to maintain categoryList<String> categories = new ArrayList<String>();categories.add("Mobile Phones");categories.add("Tablets");categories.add("Mobile Accessories");categories.add("Laptops");categories.add("Laptop Accessories");for(String category: categories){Map<String, List<RowItem>> value = categoryWiseStock.get(category);createSheet(wb, category + " - " + nextDay, value.get(nextDay));createSheet(wb, category + " - " + notNextDay, value.get(notNextDay));createSheet(wb, category + " - " + notAvailable, value.get(notAvailable));}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(DELIVERY_DAYS).setCellValue("Delivery Days");headerRow.createCell(TOTAL_AVAILABILITY).setCellValue("Total Availability");headerRow.createCell(TOTAL_RESERVED).setCellValue("Total Reserved");headerRow.createCell(WH1_AVAILABILITY).setCellValue("901 Availabality");headerRow.createCell(WH1_RESERVED).setCellValue("901 Reserved");headerRow.createCell(WH5_AVALABILITY).setCellValue("9D2 Availabality");headerRow.createCell(WH5_RESERVED).setCellValue("9D2 Reserved");headerRow.createCell(WH7_AVALABILITY).setCellValue("MP Availabality");headerRow.createCell(WH7_RESERVED).setCellValue("MP Reserved");headerRow.createCell(RISKY).setCellType(Cell.CELL_TYPE_STRING);headerRow.getCell(RISKY).setCellValue("Risky");headerRow.createCell(EXPECTED_DELAY).setCellValue("Expected Delay");headerRow.createCell(STICKY).setCellType(Cell.CELL_TYPE_STRING);headerRow.getCell(STICKY).setCellValue("Sticky");headerRow.createCell(SIMILAR_ITEMS).setCellType(Cell.CELL_TYPE_STRING);headerRow.getCell(SIMILAR_ITEMS).setCellValue("Similar Items");// headerRow.createCell(WH2_A).setCellValue("WH2 Availabality");// headerRow.createCell(WH3_A).setCellValue("WH3 Availabality");// headerRow.createCell(WH4_A).setCellValue("WH4 Availabality");// headerRow.createCell(WH2_R).setCellValue("WH2 Reserved");// headerRow.createCell(WH3_R).setCellValue("WH3 Reserved");// headerRow.createCell(WH4_R).setCellValue("WH4 Reserved");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(DELIVERY_DAYS).setCellValue(item.deliveryEstimate);contentRow.createCell(TOTAL_AVAILABILITY).setCellValue(item.totalAvailability);contentRow.createCell(TOTAL_RESERVED).setCellValue(item.totalReserved);contentRow.createCell(WH1_AVAILABILITY).setCellValue(item.wh1Availability);contentRow.createCell(WH1_RESERVED).setCellValue(item.wh1Reserved);contentRow.createCell(WH5_AVALABILITY).setCellValue(item.wh5Availability);contentRow.createCell(WH5_RESERVED).setCellValue(item.wh5Reserved);contentRow.createCell(WH7_AVALABILITY).setCellValue(item.wh7Availability);contentRow.createCell(WH7_RESERVED).setCellValue(item.wh7Reserved);contentRow.createCell(RISKY).setCellValue(item.risky);contentRow.createCell(EXPECTED_DELAY).setCellValue(item.expectedDelay);contentRow.createCell(STICKY).setCellValue(item.sticky);contentRow.createCell(SIMILAR_ITEMS).setCellValue(item.similarItems);}sheet.autoSizeColumn(SIMILAR_ITEMS);}public String getErrorMsg() {return errorMsg;}@Overridepublic void setServletRequest(HttpServletRequest req) {this.request = req;this.session = req.getSession();}@Overridepublic void setServletResponse(HttpServletResponse res) {this.response = res;}@Overridepublic 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 deliveryEstimate = 0;public long totalAvailability = 0;public long totalReserved = 0;public long wh1Availability = 0;public long wh1Reserved = 0;public long wh5Availability = 0;public long wh5Reserved = 0;public long wh7Availability = 0;public long wh7Reserved = 0;public String similarItems = "";public String risky;public String sticky;public long expectedDelay = 0;public RowItem(Item item, long estimate, ItemInventory itemInventory){id = item.getId();brand = item.getBrand();modelNumber = item.getModelNumber();modelName = item.getModelName();color = item.getColor();deliveryEstimate = estimate;risky = item.isRisky() ? "True" : "False";sticky = item.isIsWarehousePreferenceSticky() ? "True" : "False";expectedDelay = item.getExpectedDelay();totalAvailability = 0;for(Map.Entry<Long, Long> entry : itemInventory.getAvailability().entrySet()){long value = entry.getValue();switch (entry.getKey().intValue()) {case 1:wh1Availability = value;break;case 5:wh5Availability = value;break;case 7:wh7Availability = value;break;default:break;}totalAvailability += value;}for(Map.Entry<Long, Long> entry : itemInventory.getReserved().entrySet()){long value = entry.getValue();switch (entry.getKey().intValue()) {case 1:wh1Reserved = value;break;case 5:wh5Reserved = value;break;case 7:wh7Reserved = value;break;default:break;}totalReserved += value;}}}}