package com.gpc.server.servlet; import java.io.Writer; import java.math.BigDecimal; import java.rmi.RemoteException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import com.gpc.common.ApplicationContext; import com.gpc.common.PointOfSaleException; import com.gpc.common.Profile; import com.gpc.common.exception.ApplicationException; import com.gpc.common.util.FwoUtil; import com.gpc.common.util.PartNumberFormatCertifier; import com.gpc.server.dataaccess.customer.Customer; import com.gpc.server.inventory.dataaccess.Inventory; import com.gpc.server.price.dataaccess.PriceLoader; import com.gpc.valueobjects.customer.CustomerVO; import com.gpc.valueobjects.inventory.InventoryVO; import com.gpc.valueobjects.price.PricesInVO; import com.gpc.valueobjects.price.PricesOutVO; import com.gpc.valueobjects.profile.StoreProfileVO; /** * This class is used to retrieve the price attributes including tax from 'GetPrice' functionality. * * @author $Author: * * @version $Revision: $, $Date: $ */ public class GetPriceServlet extends HttpServlet { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 14236536576577L; /** The logger. */ private static Logger logger = Logger.getLogger(GetPriceServlet.class); /** The Constant CUSTOMER_NUMBER. */ private static final String CUSTOMER_NUMBER = "CUSTOMER_NUMBER"; /** The Constant PART_NUMBER. */ private static final String PART_NUMBER = "PART_NUMBER"; /** The Constant LINE_ABBREV. */ private static final String LINE_ABBREV = "LINE_ABBREV"; /** The Constant LOC. */ private static final String LOC = "LOC"; /** The Constant CONTENT_TYPE. */ private static final String CONTENT_TYPE = "text/plain"; /** The Constant PIPE. */ private static final String PIPE = "|"; /** The Constant COMMA. */ private static final String COMMA = ", "; /** The Constant EMPTY_STRING. */ private static final String EMPTY_STRING = ""; /** The Constant NEW_LINE. */ private static final String NEW_LINE = "\n"; /** The Constant ZERO. */ private static final BigDecimal ZERO = new BigDecimal("0.0000"); /* * (non-Javadoc) * * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) */ public void init(javax.servlet.ServletConfig config) throws javax.servlet.ServletException { super.init(config); } /* * (non-Javadoc) * * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ public void service(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { Writer writer = response.getWriter(); response.setContentType(CONTENT_TYPE); final String customerNumber = request.getParameter(CUSTOMER_NUMBER); String partNumber = request.getParameter(PART_NUMBER); if(partNumber != null) { partNumber = FwoUtil.stripChars(partNumber, new char[] { PartNumberFormatCertifier.DASH, PartNumberFormatCertifier.FORWARD_SLASH, PartNumberFormatCertifier.PERIOD, PartNumberFormatCertifier.SPACE }); } final String lineAbbrev = request.getParameter(LINE_ABBREV); final String location = request.getParameter(LOC); final String errorMessage = validateInputParameters(partNumber, lineAbbrev, customerNumber, location); if (errorMessage != null && errorMessage.trim().length() > 0) { writer.write(errorMessage); } else { writer.write(getPriceDetails(partNumber, lineAbbrev, new Integer(customerNumber), new Integer(location))); } response.setHeader("Cache-Control", "no-cache"); response.addHeader("Cache-Control", "no-store"); response.setHeader("Cache-Control", "max-age=0"); response.setHeader("Pragma", "no-cache"); // Avoids caching at proxy / gateway servers response.setDateHeader("Expires", 0); writer.write(NEW_LINE); writer.close(); return; } /** * Method is used to fetch the price attributes and display price attributes including all * applicable taxes from 'GetPrice' functionality. * * @param partNumber is the part number. * * @param lineAbbrev is the line abbreviation * * @param customerNumber is the customer number. * * @param location is the location values * * @return a string containing the price attributes retrieved from 'GetPrice' functionality. */ private String getPriceDetails(final String partNumber, final String lineAbbrev, final Integer customerNumber, Integer location) { // Get Store Profile Details final StoreProfileVO storeProfileVO = ApplicationContext.getInstance() .getProfile(Profile.SERVER, location.intValue()).getStoreProfile(); if (storeProfileVO == null) { return "ERROR - Store information not found"; } // Get Customer Details final CustomerVO customerVO = getCustomerDetails(customerNumber, storeProfileVO, location); if (customerVO == null) { return "ERROR - Customer information not found"; } // Get Inventory Details final InventoryVO inventoryVO = getInventoryDetails(partNumber, lineAbbrev, customerVO, storeProfileVO, location); if (inventoryVO == null) { return "ERROR - Part not found "; } // Load price from 'GetPrice' functionality final PricesOutVO priceOutputVO = getPriceDetails(partNumber, lineAbbrev, customerVO, location); if (priceOutputVO == null) { return "ERROR - Price information not found"; } return buildGetPriceServletResponse(priceOutputVO, storeProfileVO); } /** * Method is used to validate Get Price servlet input parameters * * @param partNumber is the part number * * @param lineAbbrev is the line abbreviation * * @param customerNumber is the customer number * * @param locationValue is the location value. * * @return a message containing validation results */ private String validateInputParameters(final String partNumber, final String lineAbbrev, final String customerNumber, final String locationValue) { final StringBuffer missingInputParams = new StringBuffer(); String errorMessage = null; boolean invalidParameter = false; if (isEmpty(customerNumber)) { missingInputParams.append("Customer Number"); invalidParameter = true; } if (isEmpty(partNumber)) { missingInputParams.append(invalidParameter ? COMMA : EMPTY_STRING) .append("Part Number"); invalidParameter = true; } if (isEmpty(lineAbbrev)) { missingInputParams.append(invalidParameter ? COMMA : EMPTY_STRING) .append("Line Abbreviation"); invalidParameter = true; } if (isEmpty(locationValue)) { missingInputParams.append(invalidParameter ? COMMA : EMPTY_STRING).append("Location"); invalidParameter = true; } if (invalidParameter) { errorMessage = "ERROR - Input parameter missing : " + missingInputParams.toString(); } if (errorMessage == null) { if (!isNumeric(locationValue) || !isNumeric(customerNumber)) { errorMessage = "ERROR - Customer Number or Location value should be numeric "; } } return errorMessage; } /** * Method is used to fetch the customer details. * * @param customerNumber is the customer number * * @param {@link StoreProfileVO} value object containing store profile information. * * @param location is the location value. * * @return {@link CustomerVO} value object containing customer information. */ private CustomerVO getCustomerDetails(final Integer customerNumber, final StoreProfileVO storeProfileVO, Integer location) { CustomerVO customerVO = null; try { customerVO = new Customer().getCustomerDetailInfo(location, customerNumber, storeProfileVO.getRefLanguageCd()); } catch (PointOfSaleException exception) { logger.error(exception.getMessage(), exception); } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); } return customerVO; } /** * Method is used to fetch the inventory details based on part number and line abbreviation * * @param partNumber is the part number. * * @param lineAbbrev is the line abbreviation. * * @param {@link CustomerVO} value object containing customer information. * * @param {@link StoreProfileVO} value object containing store profile information. * * @param location is the location value. * * @return {@link InventoryVO} value object containing inventory information. */ private InventoryVO getInventoryDetails(final String partNumber, final String lineAbbrev, final CustomerVO customerVO, final StoreProfileVO storeProfileVO, Integer location) { InventoryVO inventoryVO = null; Inventory inventory = new Inventory(); try { inventoryVO = inventory.getPartDetailInfo(customerVO, location, partNumber, lineAbbrev, storeProfileVO.getRefLanguageCd(), true); } catch (RemoteException remoteException) { logger.error(remoteException.getMessage(), remoteException); } catch (PointOfSaleException exception) { logger.error(exception.getMessage(), exception); } return inventoryVO; } /** * Method is used to fetch the price attributes from 'GetPrice' functionality. * * @param partNumber is the part number * * @param lineAbbrev is the line abbreviation * * @param {@link CustomerVO} value object containing customer information * * @param location is the location value. * * @return {@link PricesOutVO} value object containing 'GetPrice' functionality output values. */ private PricesOutVO getPriceDetails(final String partNumber, final String lineAbbrev, final CustomerVO customerVO, final Integer location) { final String methodSpec = "GetPriceServlet.getPriceDetails - "; PricesOutVO pricesOutVO = null; final PricesInVO pricesInputVO = new PricesInVO(); pricesInputVO.setLocation(location); pricesInputVO.setCustomerId(customerVO.getID()); pricesInputVO.setCustomerTypeCD(customerVO.getCustomerTypeCD()); pricesInputVO.setPartNumber(partNumber); pricesInputVO.setLineAbbreviation(lineAbbrev); pricesInputVO.setFieldsPassedIn("N"); final PriceLoader priceLoader = new PriceLoader(); try { pricesOutVO = priceLoader.getPrices(pricesInputVO); } catch (PointOfSaleException pointOfSaleException) { logger.error(methodSpec + " Error occured while loading getPrice details " + pointOfSaleException); } return pricesOutVO; } /** * Method is used to build the GetPriceServlet response based on the price attributes retrieved * from 'GetPrice' functionality. * * @param {@link PricesOutVO} value object containing 'GetPrice' details. * * @param {@link StoreProfileVO} value object containing store profile information * * @return a value containing all the 'Get Price' attributes separated by pipe delimiter. */ private String buildGetPriceServletResponse(final PricesOutVO priceOutputVO, final StoreProfileVO storeProfileVO) { final String methodSpec = "GetPriceServlet.buildGetPriceServletResponse -"; boolean displayPriceWithTax = storeProfileVO.getIncludeTaxInPrice().booleanValue(); final StringBuffer response = new StringBuffer(); if (displayPriceWithTax) { response.append(formatPriceValue(priceOutputVO.getDisplayListPrice())); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayUnitPrice())); response.append(PIPE); response.append(priceOutputVO.getPriceDecision()); response.append(PIPE); response.append(priceOutputVO.getCalcString()); response.append(PIPE); response.append(priceOutputVO.getMarkup()); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayUnitCost())); response.append(PIPE); response.append(priceOutputVO.getUnitRebate()); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayCoreCost())); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayCorePrice())); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayUsualPrice())); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplayCustomPrice())); response.append(PIPE); response.append(formatPriceValue(priceOutputVO.getDisplaySpecialPrice())); } else { response.append(priceOutputVO.getCalculatedList()); response.append(PIPE); response.append(priceOutputVO.getUnitPrice()); response.append(PIPE); response.append(priceOutputVO.getPriceDecision()); response.append(PIPE); response.append(priceOutputVO.getCalcString()); response.append(PIPE); response.append(priceOutputVO.getMarkup()); response.append(PIPE); response.append(priceOutputVO.getUnitCost()); response.append(PIPE); response.append(priceOutputVO.getUnitRebate()); response.append(PIPE); response.append(priceOutputVO.getCoreCost()); response.append(PIPE); response.append(priceOutputVO.getCorePrice()); response.append(PIPE); response.append(priceOutputVO.getUsualPrice()); response.append(PIPE); response.append(priceOutputVO.getCustomPrice()); response.append(PIPE); response.append(priceOutputVO.getSpecialPrice()); } if( response.length() > 0) { response.append(PIPE);//Adding Unit Saved to response. response.append(priceOutputVO.getUnitSaved()); } logger.debug(methodSpec + response.toString()); return response.toString(); } /** * Method is used to format the price value to 4 decimal places. * * @param price is the input price value * * @return price value formatted to four decimal places */ private BigDecimal formatPriceValue(BigDecimal price) { return price != null ? price.setScale(4) : ZERO; } /** * Method is used to check whether the given input param is empty or not. * * @param inputParam is the input param value. * * @return a boolean value to indicate whether the given input param is empty or not. */ private boolean isEmpty(final String inputParam) { return inputParam == null || inputParam.trim().length() <= 0; } /** * Method is used to check whether the given input param is numeric or not. * * @param inputParam is the input param value. * * @return a boolean value to indicate whether the given input param is numeric or not. */ private boolean isNumeric(final String inputParam) { boolean isNumeric = true; try { Integer.parseInt(inputParam); } catch (NumberFormatException numberFormatException) { isNumeric = false; } return isNumeric; } /* * (non-Javadoc) * * @see javax.servlet.GenericServlet#getServletConfig() */ public javax.servlet.ServletConfig getServletConfig() { return super.getServletConfig(); } /* * (non-Javadoc) * * @see javax.servlet.GenericServlet#getServletInfo() */ public String getServletInfo() { return super.getServletInfo(); } /* * (non-Javadoc) * * @see javax.servlet.GenericServlet#destroy() */ public void destroy() { super.destroy(); } }