org.apache.ofbiz.pricat.sample.SamplePricatParser.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ofbiz.pricat.sample.SamplePricatParser.java

Source

/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.apache.ofbiz.pricat.sample;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.poi.POIXMLException;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.commons.fileupload.FileItem;
import org.apache.ofbiz.pricat.AbstractPricatParser;
import org.apache.ofbiz.htmlreport.InterfaceReport;
import org.apache.ofbiz.order.finaccount.FinAccountHelper;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.transaction.GenericTransactionException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;

/**
 * Sample pricat excel parser.
 * 
 */
public class SamplePricatParser extends AbstractPricatParser {

    public static final String module = SamplePricatParser.class.getName();

    public static final Map<String, List<Object[]>> ColNamesList = UtilMisc.toMap("V1.1",
            genExcelHeaderNames("V1.1"));

    public static final int headerRowNo = 4;

    private List<String> headerColNames = new ArrayList<String>();

    public SamplePricatParser(LocalDispatcher dispatcher, Delegator delegator, Locale locale,
            InterfaceReport report, Map<String, String[]> facilities, File pricatFile, GenericValue userLogin) {
        super(dispatcher, delegator, locale, report, facilities, pricatFile, userLogin);
    }

    /**
     * Parse pricat excel file in xlsx format.
     * 
     */
    public void parsePricatExcel(boolean writeFile) {
        XSSFWorkbook workbook = null;
        try {
            // 1. read the pricat excel file
            FileInputStream is = new FileInputStream(pricatFile);

            // 2. use POI to load this bytes
            report.print(UtilProperties.getMessage(resource, "ParsePricatFileStatement",
                    new Object[] { pricatFile.getName() }, locale), InterfaceReport.FORMAT_DEFAULT);
            try {
                workbook = new XSSFWorkbook(is);
                report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
            } catch (IOException e) {
                report.println(e);
                report.println(UtilProperties.getMessage(resource, "PricatSuggestion", locale),
                        InterfaceReport.FORMAT_ERROR);
                return;
            } catch (POIXMLException e) {
                report.println(e);
                report.println(UtilProperties.getMessage(resource, "PricatSuggestion", locale),
                        InterfaceReport.FORMAT_ERROR);
                return;
            }

            // 3. only first sheet will be parsed
            // 3.1 verify the file has a sheet at least
            formatter = new HSSFDataFormatter(locale);
            isNumOfSheetsOK(workbook);

            // 3.2 verify the version is supported
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (!isVersionSupported(sheet)) {
                return;
            }

            // 3.3 get currencyId
            existsCurrencyId(sheet);

            // 3.4 verify the table header row is just the same as column names, if not, print error and return
            if (!isTableHeaderMatched(sheet)) {
                return;
            }

            // 3.5 verify the first table has 6 rows at least
            containsDataRows(sheet);

            if (UtilValidate.isNotEmpty(errorMessages)) {
                report.println(UtilProperties.getMessage(resource, "HeaderContainsError", locale),
                        InterfaceReport.FORMAT_ERROR);
                return;
            }

            // 4. parse data
            // 4.1 parse row by row and store the contents into database
            parseRowByRow(sheet);
            if (UtilValidate.isNotEmpty(errorMessages)) {
                report.println(UtilProperties.getMessage(resource, "DataContainsError", locale),
                        InterfaceReport.FORMAT_ERROR);
                if (writeFile) {
                    sequenceNum = report.getSequenceNum();
                    writeCommentsToFile(workbook, sheet);
                }
            }

            // 5. clean up the log files and commented Excel files
            cleanupLogAndCommentedExcel();
        } catch (IOException e) {
            report.println(e);
            Debug.logError(e, module);
        } finally {
            if (UtilValidate.isNotEmpty(fileItems)) {
                // remove tmp files
                FileItem fi = null;
                for (int i = 0; i < fileItems.size(); i++) {
                    fi = fileItems.get(i);
                    fi.delete();
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    Debug.logError(e, module);
                }
            }
        }
    }

    public boolean existsCurrencyId(XSSFSheet sheet) {
        report.print(UtilProperties.getMessage(resource, "StartCheckCurrencyId", locale),
                InterfaceReport.FORMAT_NOTE);
        XSSFCell currencyIdCell = sheet.getRow(2).getCell(1);
        currencyId = currencyIdCell.getStringCellValue().trim().toUpperCase();
        if (UtilValidate.isEmpty(currencyId)) {
            String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdRequired", locale);
            report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
            errorMessages.put(new CellReference(currencyIdCell), errorMessage);
            return false;
        } else {
            try {
                GenericValue currencyUom = delegator.findOne("Uom", UtilMisc.toMap("uomId", currencyId), false);
                if (!"CURRENCY_MEASURE".equals(currencyUom.getString("uomTypeId"))) {
                    String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdNotCurrency",
                            new Object[] { currencyId }, locale);
                    report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
                    errorMessages.put(new CellReference(currencyIdCell), errorMessage);
                    return false;
                }
            } catch (GenericEntityException e) {
                String errorMessage = UtilProperties.getMessage(resource, "CurrencyIdNotFound",
                        new Object[] { currencyId }, locale);
                report.println(errorMessage, InterfaceReport.FORMAT_ERROR);
                errorMessages.put(new CellReference(currencyIdCell), errorMessage);
                return false;
            }
            report.print(UtilProperties.getMessage(resource, "CurrencyIdIs", new Object[] { currencyId }, locale),
                    InterfaceReport.FORMAT_NOTE);
            report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        }
        return true;
    }

    public void parseRowByRow(XSSFSheet sheet) {
        int rows = sheet.getPhysicalNumberOfRows();
        List<Object[]> colNames = ColNamesList.get(pricatFileVersion);
        int colNumber = colNames.size();

        int emptyRowStart = -1;
        int emptyRowEnd = -1;
        for (int i = headerRowNo + 1; i < rows; i++) {
            XSSFRow row = sheet.getRow(i);
            if (UtilValidate.isEmpty(row) || isEmptyRow(row, colNumber, false)) {
                if (emptyRowStart == -1) {
                    report.print("(" + (i + 1) + ") ", InterfaceReport.FORMAT_NOTE);
                    emptyRowStart = i;
                } else {
                    emptyRowEnd = i;
                }
                continue;
            } else {
                if (emptyRowStart != -1) {
                    if (emptyRowEnd != -1) {
                        report.print(" - (" + (emptyRowEnd + 1) + ") ", InterfaceReport.FORMAT_NOTE);
                    }
                    report.print(UtilProperties.getMessage(resource, "ExcelEmptyRow", locale),
                            InterfaceReport.FORMAT_NOTE);
                    report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale),
                            InterfaceReport.FORMAT_NOTE);
                    emptyRowStart = -1;
                    emptyRowEnd = -1;
                }
            }
            report.print("(" + (i + 1) + ") ", InterfaceReport.FORMAT_NOTE);
            List<Object> cellContents = getCellContents(row, colNames, colNumber);
            try {
                if (parseCellContentsAndStore(row, cellContents)) {
                    report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale),
                            InterfaceReport.FORMAT_OK);
                } else {
                    report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale),
                            InterfaceReport.FORMAT_NOTE);
                }
            } catch (GenericTransactionException e) {
                report.println(e);
            }
        }
        if (emptyRowEnd != -1) {
            report.print(" - (" + (emptyRowEnd + 1) + ") ", InterfaceReport.FORMAT_NOTE);
            report.print(UtilProperties.getMessage(resource, "ExcelEmptyRow", locale), InterfaceReport.FORMAT_NOTE);
            report.println(" ... " + UtilProperties.getMessage(resource, "skipped", locale),
                    InterfaceReport.FORMAT_NOTE);
        }
    }

    /**
     * Check data according to business logic. If data is ok, store it.
     * 
     * @param row
     * @param cellContents
     * @param document
     * @return
     * @throws GenericTransactionException 
     */
    public boolean parseCellContentsAndStore(XSSFRow row, List<Object> cellContents)
            throws GenericTransactionException {
        if (UtilValidate.isEmpty(cellContents)) {
            return false;
        }
        switch (pricatFileVersion) {
        case "V1.1":
        default:
            return parseCellContentsAndStoreV1_X(row, cellContents);
        }
    }

    private boolean parseCellContentsAndStoreV1_X(XSSFRow row, List<Object> cellContents)
            throws GenericTransactionException {
        if (UtilValidate.isEmpty(cellContents)) {
            return false;
        }
        // 1. check if facilityId is in the facilities belong to the user, or if the name is correct for the id
        String facilityName = (String) getCellContent(cellContents, "Facility Name");
        String facilityId = (String) getCellContent(cellContents, "FacilityId");
        if (!isFacilityOk(row, facilityName, facilityId))
            return false;

        // 2. get productCategoryId
        String ownerPartyId = facilities.get(facilityId)[1];
        String productCategoryId = getProductCategoryId(cellContents, ownerPartyId);

        // 3. get productFeatureId of brand
        String brandName = (String) getCellContent(cellContents, "Brand");
        String brandId = getBrandId(brandName, ownerPartyId);
        if (UtilValidate.isEmpty(brandId)) {
            return false;
        }

        // 4. get productId from brandId, model name
        String modelName = (String) getCellContent(cellContents, "Style No");
        String productName = (String) getCellContent(cellContents, "Product Name");
        BigDecimal listPrice = (BigDecimal) getCellContent(cellContents, "List Price");
        String productId = getProductId(row, brandId, modelName, productName, productCategoryId, ownerPartyId,
                listPrice);
        if (UtilValidate.isEmpty(productId) || UtilValidate.isEmpty(listPrice)) {
            return false;
        }

        // 5. update color and size if necessary
        String color = (String) getCellContent(cellContents, "Color");
        if (UtilValidate.isEmpty(color) || UtilValidate.isEmpty(color.trim())) {
            color = defaultColorName;
        }
        String dimension = (String) getCellContent(cellContents, "Size");
        if (UtilValidate.isEmpty(dimension) || UtilValidate.isEmpty(dimension.trim())) {
            dimension = defaultDimensionName;
        }
        Map<String, Object> features = updateColorAndDimension(productId, ownerPartyId, color, dimension);
        if (ServiceUtil.isError(features)) {
            if (features.containsKey("index") && String.valueOf(features.get("index")).contains("0")) {
                int cell = headerColNames.indexOf("Color");
                XSSFCell colorCell = row.getCell(cell);
                errorMessages.put(new CellReference(colorCell),
                        UtilProperties.getMessage(resource, "PricatColorError", locale));
            }
            if (features.containsKey("index") && String.valueOf(features.get("index")).contains("1")) {
                int cell = headerColNames.indexOf("Size");
                XSSFCell colorCell = row.getCell(cell);
                errorMessages.put(new CellReference(colorCell),
                        UtilProperties.getMessage(resource, "PricatDimensionError", locale));
            }
            return false;
        }
        String colorId = (String) features.get("colorId");
        String dimensionId = (String) features.get("dimensionId");

        // 6. update skuIds by productId
        String barcode = (String) getCellContent(cellContents, "Barcode");
        BigDecimal inventory = (BigDecimal) getCellContent(cellContents, "Stock Qty");
        BigDecimal averageCost = (BigDecimal) getCellContent(cellContents, "Average Cost");
        String skuId = updateSku(row, productId, ownerPartyId, facilityId, barcode, inventory, colorId, color,
                dimensionId, dimension, listPrice, averageCost);
        if (UtilValidate.isEmpty(skuId)) {
            return false;
        }

        // 7. store prices
        BigDecimal memberPrice = (BigDecimal) getCellContent(cellContents, "Member Price");
        Map<String, Object> results = updateSkuPrice(skuId, ownerPartyId, memberPrice);
        if (ServiceUtil.isError(results)) {
            return false;
        }

        return true;
    }

    public String updateSku(XSSFRow row, String productId, String ownerPartyId, String facilityId, String barcode,
            BigDecimal inventory, String colorId, String color, String dimensionId, String dimension,
            BigDecimal listPrice, BigDecimal averageCost) {
        return "sampleSkuId";
    }

    public String getProductId(XSSFRow row, String brandId, String modelName, String productName,
            String productCategoryId, String ownerPartyId, BigDecimal listPrice) {
        return "sampleProductId";
    }

    public Object getCellContent(List<Object> cellContents, String colName) {
        if (UtilValidate.isNotEmpty(headerColNames) && headerColNames.contains(colName)) {
            return cellContents.get(headerColNames.indexOf(colName));
        }
        return null;
    }

    public String getProductCategoryId(List<Object> cellContents, String ownerPartyId) {
        return "sampleProductCategoryId";
    }

    public boolean isFacilityOk(XSSFRow row, String facilityName, String facilityId) {
        if (!facilities.containsKey(facilityId)) {
            if (UtilValidate.isEmpty(facilityId) && facilities.keySet().size() == 1) {
                if (UtilValidate.isEmpty(facilityName)) {
                    return true;
                } else {
                    String theFacilityId = (String) facilities.keySet().toArray()[0];
                    String name = facilities.get(theFacilityId)[0];
                    if (!name.equals(facilityName)) {
                        String errorMessage = UtilProperties.getMessage(resource, "FacilityNameNotMatchId",
                                new Object[] { theFacilityId, name, facilityName }, locale);
                        report.println();
                        report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                        XSSFCell cell = row.getCell(0);
                        errorMessages.put(new CellReference(cell), errorMessage);
                        return false;
                    }
                }
            } else {
                String errorMessage = UtilProperties.getMessage(resource, "FacilityNotBelongToYou",
                        new Object[] { facilityName, facilityId }, locale);
                report.println();
                report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                XSSFCell cell = row.getCell(1);
                errorMessages.put(new CellReference(cell), errorMessage);
                return false;
            }
        } else {
            String name = facilities.get(facilityId)[0];
            if (!name.equals(facilityName)) {
                String errorMessage = UtilProperties.getMessage(resource, "FacilityNameNotMatchId",
                        new Object[] { facilityId, name, facilityName }, locale);
                report.println();
                report.print(errorMessage, InterfaceReport.FORMAT_ERROR);
                XSSFCell cell = row.getCell(0);
                errorMessages.put(new CellReference(cell), errorMessage);
                return false;
            }
        }
        return true;
    }

    public boolean isTableHeaderMatched(XSSFSheet sheet) {
        List<Object[]> columnNames = ColNamesList.get(pricatFileVersion);
        short cols = sheet.getRow(headerRowNo).getLastCellNum();
        report.print(UtilProperties.getMessage(resource, "StartCheckHeaderColNum",
                new Object[] { pricatFileVersion }, locale), InterfaceReport.FORMAT_NOTE);
        if (cols != columnNames.size()) {
            report.print(
                    UtilProperties.getMessage(resource, "HeaderColNumNotMatch",
                            new Object[] { String.valueOf(cols), String.valueOf(columnNames.size()) }, locale),
                    InterfaceReport.FORMAT_WARNING);
            if (cols < columnNames.size()) {
                report.println(
                        UtilProperties.getMessage(resource, "HeaderColNumShortThanRequired",
                                new Object[] { String.valueOf(columnNames.size()) }, locale),
                        InterfaceReport.FORMAT_ERROR);
                return false;
            } else {
                report.println(
                        UtilProperties.getMessage(resource, "UseHeaderColNum",
                                new Object[] { String.valueOf(columnNames.size()) }, locale),
                        InterfaceReport.FORMAT_WARNING);
                cols = (short) columnNames.size();
            }
        } else {
            report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        }

        report.print(UtilProperties.getMessage(resource, "StartCheckHeaderColLabel",
                new Object[] { pricatFileVersion }, locale), InterfaceReport.FORMAT_NOTE);
        boolean foundLabelNotMatch = false;
        for (int i = 0; i < cols; i++) {
            String coltext = sheet.getRow(headerRowNo).getCell(i).getStringCellValue().trim();
            headerColNames.add(coltext);
            Object[] versionColumn = columnNames.get(i);
            if (!coltext.equals(versionColumn[0])) {
                report.println(UtilProperties.getMessage(resource, "HeaderColLabelNotMatch", new Object[] {
                        String.valueOf(headerRowNo + 1), String.valueOf(i + 1), coltext, versionColumn[0] },
                        locale), InterfaceReport.FORMAT_ERROR);
                foundLabelNotMatch = true;
            } else {
                report.print(" " + coltext, InterfaceReport.FORMAT_NOTE);
                if (i < cols - 1) {
                    report.print(",", InterfaceReport.FORMAT_NOTE);
                }
            }
        }
        if (foundLabelNotMatch) {
            report.println();
            return false;
        }
        report.println(" ... " + UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        return true;
    }

    public boolean isVersionSupported(XSSFSheet sheet) {
        report.print(UtilProperties.getMessage(resource, "StartCheckPricatVersion", locale),
                InterfaceReport.FORMAT_NOTE);
        pricatFileVersion = sheet.getRow(2).getCell(0).getStringCellValue().trim();
        if (ColNamesList.containsKey(pricatFileVersion)) {
            report.print(" " + pricatFileVersion + " ... ", InterfaceReport.FORMAT_NOTE);
            report.println(UtilProperties.getMessage(resource, "ok", locale), InterfaceReport.FORMAT_OK);
        } else {
            report.println(UtilProperties.getMessage(resource, "error", locale), InterfaceReport.FORMAT_ERROR);
            report.println(UtilProperties.getMessage(resource, "PricatVersionNotSupport",
                    new Object[] { pricatFileVersion }, locale), InterfaceReport.FORMAT_ERROR);
            return false;
        }
        return true;
    }

    public boolean containsDataRows(XSSFSheet sheet) {
        int rows = sheet.getPhysicalNumberOfRows();
        if (rows > headerRowNo + 1) {
            report.println(
                    UtilProperties
                            .getMessage(resource, "PricatTableRows",
                                    new Object[] { String.valueOf(headerRowNo + 1),
                                            String.valueOf(rows - headerRowNo - 1), sheet.getSheetName() },
                                    locale),
                    InterfaceReport.FORMAT_NOTE);
        } else {
            report.println(UtilProperties.getMessage(resource, "PricatNoDataRows",
                    new Object[] { sheet.getSheetName() }, locale), InterfaceReport.FORMAT_ERROR);
            return false;
        }
        return true;
    }

    /**
     * The Object[] have 4 elements, they are:
     * 1. Header Label Name.
     * 2. Cell data type to return.
     * 3. Boolean value to indicate whether the column is required.
     * 4. Boolean value to indicate whether the column is a price when cell data type is BigDecimal, this element is optional.
     * 
     * @param version
     * @return List of Object[]
     */
    private static List<Object[]> genExcelHeaderNames(String version) {
        switch (version) {
        case "V1.1":
        default:
            return genExcelHeaderNamesV1_1();
        }
    }

    /**
     * Get V1.1 pricat excel header names and attributes. 
     * 
     * @return list of Object[]
     */
    private static List<Object[]> genExcelHeaderNamesV1_1() {
        List<Object[]> listHeaderName = new ArrayList<Object[]>();
        listHeaderName.add(new Object[] { "Facility Name", XSSFCell.CELL_TYPE_STRING, Boolean.TRUE });
        listHeaderName.add(new Object[] { "FacilityId", XSSFCell.CELL_TYPE_STRING, Boolean.TRUE });
        listHeaderName.add(new Object[] { "Category L1", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Category L2", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Category L3", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Category L4", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Brand", XSSFCell.CELL_TYPE_STRING, Boolean.TRUE });
        listHeaderName.add(new Object[] { "Style No", XSSFCell.CELL_TYPE_STRING, Boolean.TRUE });
        listHeaderName.add(new Object[] { "Product Name", XSSFCell.CELL_TYPE_STRING, Boolean.TRUE });
        listHeaderName.add(new Object[] { "Color", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Size", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Barcode", XSSFCell.CELL_TYPE_STRING, Boolean.FALSE });
        listHeaderName.add(new Object[] { "Stock Qty", XSSFCell.CELL_TYPE_NUMERIC, Boolean.TRUE });
        listHeaderName.add(new Object[] { "Average Cost", XSSFCell.CELL_TYPE_NUMERIC, Boolean.TRUE, Boolean.TRUE });
        listHeaderName.add(new Object[] { "List Price", XSSFCell.CELL_TYPE_NUMERIC, Boolean.TRUE, Boolean.TRUE });
        listHeaderName
                .add(new Object[] { "Member Price", XSSFCell.CELL_TYPE_NUMERIC, Boolean.FALSE, Boolean.TRUE });
        return listHeaderName;
    }

    @Override
    public void parsePricatExcel() {
        parsePricatExcel(true);
    }

    /**
     * Get data by version definition.
     * 
     * @param row
     * @param colNames 
     * @param size 
     * @return
     */
    public List<Object> getCellContents(XSSFRow row, List<Object[]> colNames, int size) {
        List<Object> results = new ArrayList<Object>();
        boolean foundError = false;
        if (isEmptyRow(row, size, true)) {
            return null;
        }

        // check and get data
        for (int i = 0; i < size; i++) {
            XSSFCell cell = null;
            if (row.getPhysicalNumberOfCells() > i) {
                cell = row.getCell(i);
            }
            if (cell == null) {
                if (((Boolean) colNames.get(i)[2]).booleanValue()
                        && (facilities.keySet().size() > 1 || (facilities.keySet().size() == 1 && i >= 2))) {
                    report.print(UtilProperties.getMessage(resource, "ErrorColCannotEmpty",
                            new Object[] { colNames.get(i)[0] }, locale), InterfaceReport.FORMAT_WARNING);
                    cell = row.createCell(i);
                    errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource,
                            "ErrorColCannotEmpty", new Object[] { colNames.get(i)[0] }, locale));
                    foundError = true;
                    results.add(null);
                    continue;
                } else {
                    cell = row.createCell(i);
                }
            }
            int cellType = cell.getCellType();
            String cellValue = formatter.formatCellValue(cell);
            if (UtilValidate.isNotEmpty(cellValue) && UtilValidate.isNotEmpty(cellValue.trim())) {
                if (cellType == XSSFCell.CELL_TYPE_FORMULA) {
                    try {
                        cellValue = BigDecimal.valueOf(cell.getNumericCellValue())
                                .setScale(FinAccountHelper.decimals, FinAccountHelper.rounding).toString();
                    } catch (IllegalStateException e) {
                        try {
                            cellValue = cell.getStringCellValue();
                        } catch (IllegalStateException e1) {
                            // do nothing
                        }
                    }
                    report.print(((i == 0) ? "" : ", ") + cellValue, InterfaceReport.FORMAT_NOTE);
                } else {
                    report.print(((i == 0) ? "" : ", ") + cellValue, InterfaceReport.FORMAT_NOTE);
                }
            } else {
                report.print(((i == 0) ? "" : ","), InterfaceReport.FORMAT_NOTE);
            }
            if (((Boolean) colNames.get(i)[2]).booleanValue() && UtilValidate.isEmpty(cellValue)
                    && (facilities.keySet().size() > 1 || (facilities.keySet().size() == 1 && i >= 2))) {
                report.print(UtilProperties.getMessage(resource, "ErrorColCannotEmpty",
                        new Object[] { colNames.get(i)[0] }, locale), InterfaceReport.FORMAT_WARNING);
                errorMessages.put(new CellReference(cell), UtilProperties.getMessage(resource,
                        "ErrorColCannotEmpty", new Object[] { colNames.get(i)[0] }, locale));
                foundError = true;
                results.add(null);
                continue;
            }
            if (((Boolean) colNames.get(i)[2]).booleanValue() && cellType != (int) colNames.get(i)[1]) {
                // String warningMessage = "";
                if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_STRING) {
                    if (UtilValidate.isNotEmpty(cellValue) && UtilValidate.isNotEmpty(cellValue.trim())) {
                        results.add(cellValue);
                    } else {
                        results.add(null);
                    }
                } else if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_NUMERIC) {
                    if (cell.getCellType() != XSSFCell.CELL_TYPE_STRING) {
                        cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                    }
                    try {
                        results.add(BigDecimal.valueOf(Double.parseDouble(cell.getStringCellValue()))
                                .setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                    } catch (NumberFormatException e) {
                        results.add(null);
                        errorMessages.put(new CellReference(cell),
                                UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                    }
                }
            } else {
                if (UtilValidate.isEmpty(cellValue) || UtilValidate.isEmpty(cellValue.trim())) {
                    results.add(null);
                    continue;
                }
                if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_STRING) {
                    if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                        cellValue = cell.getStringCellValue().trim();
                        results.add(cellValue);
                    } else {
                        results.add(cellValue.trim());
                    }
                } else if ((int) colNames.get(i)[1] == XSSFCell.CELL_TYPE_NUMERIC) {
                    if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                        try {
                            results.add(BigDecimal.valueOf(Double.valueOf(cell.getStringCellValue())));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell),
                                    UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    } else if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
                        try {
                            results.add(BigDecimal.valueOf(cell.getNumericCellValue())
                                    .setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell),
                                    UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    } else {
                        try {
                            results.add(BigDecimal.valueOf(Double.valueOf(cellValue))
                                    .setScale(FinAccountHelper.decimals, FinAccountHelper.rounding));
                        } catch (NumberFormatException e) {
                            results.add(null);
                            errorMessages.put(new CellReference(cell),
                                    UtilProperties.getMessage(resource, "ErrorParseValueToNumeric", locale));
                        }
                    }
                }
            }
        }
        if (foundError) {
            return null;
        }
        return results;
    }

    protected int getHeaderRowNo() {
        return headerRowNo;
    }
}