Added: ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlReport.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlReport.java?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlReport.java (added) +++ ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlReport.java Mon Nov 21 08:07:57 2016 @@ -0,0 +1,140 @@ +/******************************************************************************* + * 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; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.ofbiz.htmlreport.AbstractHtmlReport; +import org.apache.ofbiz.htmlreport.InterfaceReportThread; +import org.apache.ofbiz.htmlreport.util.ReportStringUtil; + +/** + * Provides a html report for running parse a PriCat file.<p> + * + */ +public class PricatParseExcelHtmlReport extends AbstractHtmlReport { + + public static final String PRICAT_REPORT_CLASS = "PRICAT_HTML_REPORT"; + + /** + * Public constructor with report variables.<p> + * + * @param req the HttpServletRequest request + * @param res the HttpServletResponse response + */ + public PricatParseExcelHtmlReport(HttpServletRequest request, HttpServletResponse response) { + + super(request, response, true, true); + } + + public static PricatParseExcelHtmlReport getReport(HttpServletRequest request, HttpServletResponse response) { + + PricatParseExcelHtmlReport wp = (PricatParseExcelHtmlReport) request.getAttribute(PRICAT_REPORT_CLASS); + if (wp == null) { + wp = new PricatParseExcelHtmlReport(request, response); + request.setAttribute(PRICAT_REPORT_CLASS, wp); + } + return wp; + } + + public InterfaceReportThread initializeThread(HttpServletRequest request, HttpServletResponse response, String name) { + + if (name == null) { + name = ""; + } + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + int i = threadGroup.activeCount(); + Thread[] threads = new Thread[i]; + threadGroup.enumerate(threads, true); + InterfaceReportThread thread = null; + for (int j=0; j<threads.length; j++) { + Thread threadInstance = threads[j]; + if (threadInstance instanceof PricatParseExcelHtmlThread) { + thread = (PricatParseExcelHtmlThread) threadInstance; + break; + } + } + if (thread == null) { + thread = new PricatParseExcelHtmlThread(request, response, name); + } + + return thread; + } + + public static String checkButton(HttpServletRequest request, HttpServletResponse response) { + String action = request.getParameter("action"); + if (ReportStringUtil.isNotEmpty(action)) { + if (action.equalsIgnoreCase("ok")) { + request.removeAttribute(PRICAT_REPORT_CLASS); + request.removeAttribute(DIALOG_URI); + return "ok"; + } else if (action.equalsIgnoreCase("cancel")) { + request.removeAttribute(PRICAT_REPORT_CLASS); + request.removeAttribute(DIALOG_URI); + return "cancel"; + } + } + action = request.getParameter("ok"); + if (ReportStringUtil.isNotEmpty(action)) { + if (action.equalsIgnoreCase("ok")) { + request.removeAttribute(PRICAT_REPORT_CLASS); + request.removeAttribute(DIALOG_URI); + return "ok"; + } + } + action = request.getParameter("cancel"); + if (ReportStringUtil.isNotEmpty(action)) { + if (action.equalsIgnoreCase("cancel")) { + request.removeAttribute(PRICAT_REPORT_CLASS); + request.removeAttribute(DIALOG_URI); + return "cancel"; + } + } + + return "success"; + } + + /** + * Performs the dialog actions depending on the initialized action.<p> + * + * @throws IOException + */ + public void prepareDisplayReport(HttpServletRequest request, HttpServletResponse response, String name, String dialogUri) throws IOException { + + if (ReportStringUtil.isNotEmpty(dialogUri)) { + setDialogRealUri(request, dialogUri); + } + + String action = getParamAction(request); + if (action == null) action = ""; + if (action.equals("reportend") || action.equals("cancel")) { + setParamAction("reportend"); + setDialogRealUri(request, dialogUri); + } else if (action.equals("reportupdate")) { + setParamAction("reportupdate"); + } else { + InterfaceReportThread thread = initializeThread(request, response, name); + thread.start(); + setParamAction("reportbegin"); + setParamThread(thread.getUUID().toString()); + } + } +} Added: ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlThread.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlThread.java?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlThread.java (added) +++ ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatParseExcelHtmlThread.java Mon Nov 21 08:07:57 2016 @@ -0,0 +1,359 @@ +/******************************************************************************* + * 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; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.ofbiz.htmlreport.AbstractReportThread; +import org.apache.ofbiz.htmlreport.InterfaceReport; +import org.apache.ofbiz.pricat.sample.SamplePricatParser; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.FileUtil; +import org.apache.ofbiz.base.util.UtilDateTime; +import org.apache.ofbiz.base.util.UtilGenerics; +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.condition.EntityCondition; +import org.apache.ofbiz.entity.condition.EntityOperator; +import org.apache.ofbiz.entity.util.EntityUtil; +import org.apache.ofbiz.service.LocalDispatcher; + +/** + * Thread for running pricat import excel html report. + * + */ +public class PricatParseExcelHtmlThread extends AbstractReportThread { + + public static final String module = PricatParseExcelHtmlThread.class.getName(); + + public static final String PARSE_EXCEL = "parse_excel"; + + public static final String CONFIRM = "confirm_action"; + + public static final String[] messageLabels = new String[] {"FORMAT_DEFAULT", "FORMAT_WARNING", "FORMAT_HEADLINE", "FORMAT_NOTE", "FORMAT_OK", "FORMAT_ERROR", "FORMAT_THROWABLE"}; + + public static final List<String> messages = Collections.unmodifiableList(Arrays.asList(messageLabels)); + + public static final String FileDateTimePattern = "yyyyMMddHHmmss"; + + public static final String defaultColorName = "DefaultColor"; + + public static final String defaultDimensionName = "DefaultDimension"; + + public static final String defaultCategoryName = "DefaultCategory"; + + public static final String EXCEL_TEMPLATE_TYPE = "excelTemplateType"; + + public static final String FACILITY_ID = "facilityId"; + + private LocalDispatcher dispatcher; + + private Delegator delegator; + + private List<FileItem> fileItems; + + private File pricatFile; + + private String userLoginId; + + private GenericValue userLogin; + + private Map<String, String[]> facilities = new HashMap<String, String[]>(); + + public static final String resource = "PricatUiLabels"; + + private HttpSession session; + + public static final String PRICAT_FILE = "__PRICAT_FILE__"; + + public static final String DEFAULT_PRICAT_TYPE = "sample_pricat"; + + private String selectedPricatType = DEFAULT_PRICAT_TYPE; + + private String selectedFacilityId; + + public static final Map<String, String> PricatTypeLabels = UtilMisc.toMap("sample_pricat", "SamplePricatTemplate", + "ofbiz_pricat", "OFBizPricatTemplate"); + + private InterfacePricatParser pricatParser; + + private String thruReasonId = "EXCEL_IMPORT_SUCCESS"; + + /** + * Constructor, creates a new html thread. + * + * @param request + * @param response + * @param name + */ + public PricatParseExcelHtmlThread(HttpServletRequest request, HttpServletResponse response, String name) { + + super(request, response, name); + dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); + setDelegator(dispatcher.getDelegator()); + userLogin = (GenericValue) request.getSession().getAttribute("userLogin"); + if (UtilValidate.isEmpty(userLogin)) { + initHtmlReport(request, response, true, true); + getReport().println(UtilProperties.getMessage(resource, "PricatRequireUserLogin", getLocale()), InterfaceReport.FORMAT_ERROR); + return; + } else { + userLoginId = userLogin.getString("userLoginId"); + session = request.getSession(); + } + + long sequenceNum = addExcelImportHistory(); + File userFolder = FileUtil.getFile(InterfacePricatParser.tempFilesFolder + userLoginId + "/"); + if (!userFolder.exists()) { + userFolder.mkdirs(); + } + String logFileName = InterfacePricatParser.tempFilesFolder + userLoginId + "/" + sequenceNum + ".log"; + initHtmlReport(request, response, true, true, logFileName); + if (sequenceNum > 0) { + getReport().setSequenceNum(sequenceNum); + getReport().addLogFile(logFileName); + } + try { + getReport().print(UtilProperties.getMessage(resource, "StartStoreExcel", getLocale()), InterfaceReport.FORMAT_HEADLINE); + ServletFileUpload dfu = new ServletFileUpload(new DiskFileItemFactory(10240, userFolder)); + fileItems = UtilGenerics.checkList(dfu.parseRequest(request)); + } catch (FileUploadException e) { + getReport().addError(e); + } + if (UtilValidate.isEmpty(fileItems)) { + getReport().println(UtilProperties.getMessage(resource, "NoFileUploaded", getLocale()), InterfaceReport.FORMAT_ERROR); + } else { + getReport().println(UtilProperties.getMessage(resource, "ok", getLocale()), InterfaceReport.FORMAT_OK); + } + } + + public String getReportUpdate() { + + return getReport().getReportUpdate(); + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() { + + try { + if (getName().startsWith(PARSE_EXCEL) && UtilValidate.isNotEmpty(fileItems)) { + getReport().println(); + getReport().println(UtilProperties.getMessage(resource, "StartParsePricat", getLocale()), InterfaceReport.FORMAT_HEADLINE); + if (prepareParse()) { + if (selectedPricatType.equals(DEFAULT_PRICAT_TYPE)) { + pricatParser = new SamplePricatParser(dispatcher, delegator, getLocale(), getReport(), facilities, pricatFile, userLogin); + } + if (UtilValidate.isEmpty(pricatParser)) { + getReport().println(UtilProperties.getMessage(resource, "NoPricatParserFor", getLocale()), InterfaceReport.FORMAT_ERROR); + } else { + pricatParser.parsePricatExcel(); + getReport().println(UtilProperties.getMessage(resource, "PricatParseCompleted", getLocale()), InterfaceReport.FORMAT_HEADLINE); + } + } + } else { + getReport().println(getName(), InterfaceReport.FORMAT_ERROR); + Debug.logError(getName(), module); + thruReasonId = "EXCEL_IMPORT_ERROR"; + } + } catch (Exception e) { + getReport().println(e); + Debug.logError(e, module); + thruReasonId = "EXCEL_IMPORT_ERROR"; + } finally { + // wait 5 seconds to wait page output + try { + sleep(5000); + } catch (InterruptedException e) { + } + // call report update to make sure all messages are output to file + getReport().getReportUpdate(); + String logFileName = getReport().closeLogFile(); + if (UtilValidate.isNotEmpty(pricatParser)) { + if (thruReasonId.equals("EXCEL_IMPORT_SUCCESS") && pricatParser.hasErrorMessages()) { + thruReasonId = "EXCEL_IMPORT_QUEST"; + } + pricatParser.endExcelImportHistory(logFileName, thruReasonId); + } + } + } + + private boolean prepareParse() throws IOException { + // 1 get facilities belong to current userLogin + facilities = getCurrentUserLoginFacilities(); + if (UtilValidate.isEmpty(facilities)) { + getReport().println(UtilProperties.getMessage(resource, "CurrentUserLoginNoFacility", new Object[]{userLoginId}, getLocale()), InterfaceReport.FORMAT_ERROR); + return false; + } else { + getReport().println(" ... " + UtilProperties.getMessage(resource, "ok", getLocale()), InterfaceReport.FORMAT_OK); + getReport().println(); + } + + // 2. store the pricat excel file + if (!storePricatFile()) { + return false; + } + return true; + } + + private boolean storePricatFile() throws IOException { + FileItem fi = null; + FileItem pricatFi = null; + byte[] pricatBytes = {}; + // check excelTemplateType + for (int i = 0; i < fileItems.size(); i++) { + fi = fileItems.get(i); + String fieldName = fi.getFieldName(); + if (fi.isFormField() && UtilValidate.isNotEmpty(fieldName)) { + if (fieldName.equals(EXCEL_TEMPLATE_TYPE)) { + selectedPricatType = fi.getString(); + } + } + } + getReport().print(UtilProperties.getMessage(resource, "ExcelTemplateTypeSelected", getLocale()), InterfaceReport.FORMAT_DEFAULT); + if (PricatTypeLabels.containsKey(selectedPricatType)) { + getReport().print(UtilProperties.getMessage(resource, PricatTypeLabels.get(selectedPricatType), getLocale()), InterfaceReport.FORMAT_DEFAULT); + getReport().println(" ... " + UtilProperties.getMessage(resource, "ok", getLocale()), InterfaceReport.FORMAT_OK); + } else { + getReport().println(UtilProperties.getMessage(resource, PricatTypeLabels.get(selectedPricatType), getLocale()), InterfaceReport.FORMAT_ERROR); + return false; + } + + // store the file + for (int i = 0; i < fileItems.size(); i++) { + fi = fileItems.get(i); + String fieldName = fi.getFieldName(); + if (fieldName.equals("filename")) { + pricatFi = fi; + pricatBytes = pricatFi.get(); + Path path = Paths.get(fi.getName()); + pricatFile = new File(InterfacePricatParser.tempFilesFolder + userLoginId + "/" + path.getFileName().toString()); + FileOutputStream fos = new FileOutputStream(pricatFile); + fos.write(pricatBytes); + fos.flush(); + fos.close(); + session.setAttribute(PRICAT_FILE, pricatFile.getAbsolutePath()); + } + } + return true; + } + + private Map<String, String[]> getCurrentUserLoginFacilities() { + getReport().println(); + getReport().println(UtilProperties.getMessage(resource, "GetCurrentUserLoginFacility", getLocale()), InterfaceReport.FORMAT_DEFAULT); + Map<String, Object> context = new HashMap<String, Object>(); + context.put("userLogin", userLogin); + context.put("locale", getLocale()); + try { + List<EntityCondition> orgConditions = new LinkedList<EntityCondition>(); + orgConditions.add(EntityCondition.makeCondition("onePartyIdFrom", EntityOperator.EQUALS, userLogin.getString("partyId"))); + orgConditions.add(EntityCondition.makeCondition("twoRoleTypeIdFrom", EntityOperator.EQUALS, "INTERNAL_ORGANIZATIO")); + orgConditions.add(EntityCondition.makeCondition("twoRoleTypeIdTo", EntityOperator.EQUALS, "EMPLOYEE")); + orgConditions.add(EntityCondition.makeCondition("twoRoleTypeIdTo", EntityOperator.EQUALS, "EMPLOYEE")); + List<GenericValue> organizations = delegator.findList("PartyRelationshipToFrom", EntityCondition.makeCondition(orgConditions), null, null, null, false); + Timestamp now = UtilDateTime.nowTimestamp(); + organizations = EntityUtil.filterByDate(organizations, now, "twoFromDate", "twoThruDate", true); + organizations = EntityUtil.filterByDate(organizations, now, "oneFromDate", "oneThruDate", true); + + List<EntityCondition> ownerPartyConditions = new LinkedList<EntityCondition>(); + Set<String> orgPartyIds = new HashSet<String>(); + for (GenericValue organization : organizations) { + String orgPartyId = organization.getString("onePartyIdTo"); + if (!orgPartyIds.contains(orgPartyId)) { + ownerPartyConditions.add(EntityCondition.makeCondition("ownerPartyId", EntityOperator.EQUALS, orgPartyId)); + orgPartyIds.add(orgPartyId); + } + } + if (UtilValidate.isEmpty(ownerPartyConditions)) { + return facilities; + } + + List<GenericValue> facilityValues = delegator.findList("Facility", EntityCondition.makeCondition(ownerPartyConditions, EntityOperator.OR), null, null, null, false); + if (UtilValidate.isNotEmpty(facilityValues)) { + int i = 1; + for (GenericValue facilityValue : facilityValues) { + if (UtilValidate.isNotEmpty(facilityValue)) { + String facilityId = facilityValue.getString("facilityId"); + if (!facilities.containsKey(facilityId)) { + String facilityName = facilityValue.getString("facilityName"); + facilities.put(facilityId, new String[] {facilityName, facilityValue.getString("ownerPartyId")}); + getReport().println(UtilProperties.getMessage(resource, "FacilityFoundForCurrentUserLogin", new Object[]{String.valueOf(i), facilityName, facilityId}, getLocale()), InterfaceReport.FORMAT_NOTE); + i++; + } + } + } + } + }catch (GenericEntityException e) { + Debug.logError(e.getMessage(), module); + } + return facilities; + } + + public Delegator getDelegator() { + return delegator; + } + + public void setDelegator(Delegator delegator) { + this.delegator = delegator; + } + + public synchronized long addExcelImportHistory() { + long latestId = 1; + try { + List<GenericValue> historyValues = delegator.findByAnd("ExcelImportHistory", UtilMisc.toMap("userLoginId", userLoginId), UtilMisc.toList("sequenceNum DESC"), false); + GenericValue latestHistoryValue = EntityUtil.getFirst(historyValues); + if (UtilValidate.isNotEmpty(latestHistoryValue)) { + latestId = latestHistoryValue.getLong("sequenceNum") + 1; + } + GenericValue newHistoryValue = delegator.makeValue("ExcelImportHistory", UtilMisc.toMap("sequenceNum", latestId, "userLoginId", userLoginId, + "fileName", pricatFile == null ? "" : pricatFile.getName(), "statusId", isAlive() ? "EXCEL_IMPORTING" : "EXCEL_IMPORTED", + "fromDate", UtilDateTime.nowTimestamp(), "threadName", getName(), "logFileName", InterfacePricatParser.tempFilesFolder + userLoginId + "/" + latestId + ".log")); + newHistoryValue.create(); + } catch (GenericEntityException e) { + Debug.logError(e, module); + return -1; + } + return latestId; + } +} Added: ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java (added) +++ ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java Mon Nov 21 08:07:57 2016 @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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.IOException; +import java.net.MalformedURLException; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.jdom.JDOMException; +import org.apache.ofbiz.base.location.ComponentLocationResolver; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.UtilHttp; +import org.apache.ofbiz.base.util.UtilProperties; +import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.pricat.PricatEvents; + +public class SamplePricatEvents extends PricatEvents { + + public static final String module = SamplePricatEvents.class.getName(); + + public static final String PricatLatestVersion = UtilProperties.getPropertyValue("pricat", "pricat.latest.version", "V1.1"); + + public static final String DemoPricatFileName = "SamplePricatTemplate_" + PricatLatestVersion + ".xlsx"; + + public static final String DemoPricatPath = "component://pricat/webapp/pricatdemo/downloads/"; + + /** + * Download excel template. + * + * @param request + * @param response + * @return + * @throws IOException + * @throws JDOMException + */ + public static String downloadExcelTemplate(HttpServletRequest request, HttpServletResponse response) { + String templateType = request.getParameter("templateType"); + if (UtilValidate.isEmpty(templateType)) { + return "error"; + } + try { + String path = ComponentLocationResolver.getBaseLocation(DemoPricatPath).toString(); + String fileName = null; + if ("pricatExcelTemplate".equals(templateType)) { + fileName = DemoPricatFileName; + } + if (UtilValidate.isEmpty(fileName)) { + return "error"; + } + Path file = Paths.get(path + fileName); + byte[] bytes = Files.readAllBytes(file); + UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8")); + } catch (MalformedURLException e) { + Debug.logError(e.getMessage(), module); + return "error"; + } catch (IOException e) { + Debug.logError(e.getMessage(), module); + return "error"; + } + return "success"; + } +} Added: ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatParser.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatParser.java?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatParser.java (added) +++ ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatParser.java Mon Nov 21 08:07:57 2016 @@ -0,0 +1,665 @@ +/******************************************************************************* + * 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; + } +} Added: ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java (added) +++ ofbiz/trunk/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java Mon Nov 21 08:07:57 2016 @@ -0,0 +1,36 @@ +/* + * 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.poi.xssf.usermodel; + +import org.apache.poi.ss.util.CellReference; +import com.microsoft.schemas.vml.CTShape; + +public final class OFBizPricatUtil { + public static void formatCommentShape(XSSFSheet sheet, CellReference cell) { + XSSFVMLDrawing vml = sheet.getVMLDrawing(true); + CTShape ctshape = vml.findCommentShape(cell.getRow(), cell.getCol()); + ctshape.setType("#_x0000_t202"); + } + + public static void formatCommentShape(XSSFSheet sheet, int rowNum, short colNum) { + XSSFVMLDrawing vml = sheet.getVMLDrawing(true); + CTShape ctshape = vml.findCommentShape(rowNum, colNum); + ctshape.setType("#_x0000_t202"); + } +} Added: ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/controller.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/controller.xml?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/controller.xml (added) +++ ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/controller.xml Mon Nov 21 08:07:57 2016 @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> + +<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://ofbiz.apache.org/Site-Conf" xsi:schemaLocation="http://ofbiz.apache.org/Site-Conf http://ofbiz.apache.org/dtds/site-conf.xsd"> + <include location="component://common/webcommon/WEB-INF/common-controller.xml"/> + <include location="component://common/webcommon/WEB-INF/portal-controller.xml"/> + + <description>PriCat</description> + + <!-- define --> + <request-map uri="main"> + <security https="true" auth="true"/> + <response name="success" type="view" value="main"/> + </request-map> + + <request-map uri="downloadCommentedExcel"> + <security https="true" auth="true"/> + <event type="java" path="org.apache.ofbiz.pricat.PricatEvents" invoke="downloadCommentedExcel"/> + <response name="success" type="none" /> + <response name="error" type="none" /> + </request-map> + + <request-map uri="viewExcelImportLog"> + <security https="true" auth="true"/> + <response name="success" type="view" value="viewExcelImportLog"/> + </request-map> + + <view-map name="main" type="screen" page="component://pricat/widget/CommonScreens.xml#viewExcelImportHistory"/> + <view-map name="viewExcelImportLog" type="screen" page="component://pricat/widget/CommonScreens.xml#viewExcelImportLog"/> +</site-conf> Added: ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/web.xml?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/web.xml (added) +++ ofbiz/trunk/specialpurpose/pricat/webapp/pricat/WEB-INF/web.xml Mon Nov 21 08:07:57 2016 @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> + +<web-app version="3.0"> + + <display-name>Apache OFBiz - PriCat</display-name> + <description>PriCat Application of the Apache OFBiz Project</description> + + <context-param> + <description>A unique name used to identify/recognize the local dispatcher for the Service Engine</description> + <param-name>localDispatcherName</param-name><param-value>pricat</param-value> + </context-param> + <context-param> + <description>The Name of the Entity Delegator to use, defined in entityengine.xml</description> + <param-name>entityDelegatorName</param-name><param-value>default</param-value> + </context-param> + <context-param> + <description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description> + <param-name>mainDecoratorLocation</param-name> + <param-value>component://pricat/widget/SampleScreens.xml</param-value> + </context-param> + <context-param> + <description>Remove unnecessary whitespace from HTML output.</description> + <param-name>compressHTML</param-name> + <param-value>false</param-value> + </context-param> + + <filter> + <display-name>ControlFilter</display-name> + <filter-name>ControlFilter</filter-name> + <filter-class>org.apache.ofbiz.webapp.control.ControlFilter</filter-class> + <init-param> + <param-name>allowedPaths</param-name> + <param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/js:/ws:/includes</param-value> + </init-param> + <init-param> + <param-name>redirectPath</param-name> + <param-value>/control/main</param-value> + </init-param> + </filter> + <filter> + <display-name>ContextFilter</display-name> + <filter-name>ContextFilter</filter-name> + <filter-class>org.apache.ofbiz.webapp.control.ContextFilter</filter-class> + </filter> + <filter-mapping> + <filter-name>ControlFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <filter-mapping> + <filter-name>ContextFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <listener><listener-class>org.apache.ofbiz.webapp.control.ControlEventListener</listener-class></listener> + <listener><listener-class>org.apache.ofbiz.webapp.control.LoginEventListener</listener-class></listener> + <!-- NOTE: not all app servers support mounting implementations of the HttpSessionActivationListener interface --> + <!-- <listener><listener-class>org.apache.ofbiz.webapp.control.ControlActivationEventListener</listener-class></listener> --> + + <servlet> + <description>Main Control Servlet</description> + <display-name>ControlServlet</display-name> + <servlet-name>ControlServlet</servlet-name> + <servlet-class>org.apache.ofbiz.webapp.control.ControlServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + <servlet-mapping><servlet-name>ControlServlet</servlet-name><url-pattern>/control/*</url-pattern></servlet-mapping> + + <session-config> + <session-timeout>60</session-timeout><!-- in minutes --> + <cookie-config> + <http-only>true</http-only> + <secure>true</secure> + </cookie-config> + <tracking-mode>COOKIE</tracking-mode> + </session-config> + + <welcome-file-list> + <welcome-file>index.jsp</welcome-file> + <welcome-file>index.html</welcome-file> + <welcome-file>index.htm</welcome-file> + </welcome-file-list> +</web-app> Added: ofbiz/trunk/specialpurpose/pricat/webapp/pricat/error/error.jsp URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/webapp/pricat/error/error.jsp?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/webapp/pricat/error/error.jsp (added) +++ ofbiz/trunk/specialpurpose/pricat/webapp/pricat/error/error.jsp Mon Nov 21 08:07:57 2016 @@ -0,0 +1,52 @@ +<%-- +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. +--%> +<%@ page import="org.apache.ofbiz.base.util.*" %> +<html> +<head> +<title>OFBiz Message</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +</head> + +<% String errorMsg = (String) request.getAttribute("_ERROR_MESSAGE_"); %> + +<body bgcolor="#FFFFFF"> +<div align="center"> + <br/> + <table width="100%" border="1" height="200"> + <tr> + <td> + <table width="100%" border="0" height="200"> + <tr bgcolor="#CC6666"> + <td height="45"> + <div align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="4" color="#FFFFFF"><b>:ERROR MESSAGE:</b></font></div> + </td> + </tr> + <tr> + <td> + <div align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><%=UtilFormatOut.replaceString(errorMsg, "\n", "<br/>")%></font></div> + </td> + </tr> + </table> + </td> + </tr> + </table> +</div> +<div align="center"></div> +</body> +</html> Added: ofbiz/trunk/specialpurpose/pricat/webapp/pricat/ftl/ExcelImportHistoryReport.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/pricat/webapp/pricat/ftl/ExcelImportHistoryReport.ftl?rev=1770621&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/pricat/webapp/pricat/ftl/ExcelImportHistoryReport.ftl (added) +++ ofbiz/trunk/specialpurpose/pricat/webapp/pricat/ftl/ExcelImportHistoryReport.ftl Mon Nov 21 08:07:57 2016 @@ -0,0 +1,109 @@ +<#-- +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. +--> +<div class="row"> + <div class="col-sm-12 m-b-xs text-left p-xs"> + <label >${uiLabelMap.ExcelImportHistoryList}</label> + <span class="tooltip pad-left30 top">${uiLabelMap.OnlyYourOwnImportHistoryDisplayed}</span> + </div> +</div> + +<div id="loadBody" style="display:none"> +</div> +<table id="productlist" name="productlist" class="table table-striped ms-table-primary"> + <thead> + <th></th> + <th>${uiLabelMap.SerialNumber}</th> + <th>${uiLabelMap.Filename}</th> + <th>${uiLabelMap.FromDate}</th> + <th>${uiLabelMap.ThruDate}</th> + <th>${uiLabelMap.ImportStatus}</th> + <th>${uiLabelMap.ThruReasonId}</th> + <th>${uiLabelMap.Actions}</th> + </thead> + <tbody> + <#if (data?has_content)> + <#list data as historyEntry> + <tr name="${historyEntry.sequenceNum!}"> + <td> + <#if historyEntry.statusId?exists && historyEntry.statusId == 'EXCEL_IMPORTING'> + <img src="/erptheme/images/blue_anime.gif" alt="${uiLabelMap.EXCE_IMPORTING}" tooltip="${uiLabelMap.EXCE_IMPORTING}"> + <#elseif historyEntry.statusId?exists && historyEntry.statusId == 'EXCEL_IMPORTED' && historyEntry.thruReasonId?exists && historyEntry.thruReasonId?has_content> + <#if historyEntry.thruReasonId == 'EXCEL_IMPORT_SUCCESS'> + <button id="excel-import-status" data-tooltip="${uiLabelMap.get(historyEntry.thruReasonId)}"><i class="icon-ok-sign success-color">${uiLabelMap.ReasonOK}</i></button> + <#elseif historyEntry.thruReasonId == 'EXCEL_IMPORT_STOPPED'> + <button id="excel-import-status" data-tooltip="${uiLabelMap.get(historyEntry.thruReasonId)}"><i class="icon-remove-sign stopped-color">${uiLabelMap.ReasonStopped}</i></button> + <#elseif historyEntry.thruReasonId == 'EXCEL_IMPORT_ERROR'> + <button id="excel-import-status" data-tooltip="${uiLabelMap.get(historyEntry.thruReasonId)}"><i class="icon-exclamation-sign error-color"></i>${uiLabelMap.ReasonError}</button> + <#elseif historyEntry.thruReasonId == 'EXCEL_IMPORT_QUEST'> + <button id="excel-import-status" data-tooltip="${uiLabelMap.get(historyEntry.thruReasonId)}"><i class="icon-question-sign question-color"></i>${uiLabelMap.ReasonWarning}</button> + </#if> + </#if> + </td> + <td>${historyEntry.sequenceNum!}</td> + <td style="text-align:right;">${historyEntry.fileName!}</td> + <td><#if historyEntry.fromDate?exists && historyEntry.fromDate?has_content>${historyEntry.fromDate?string("yyyy-MM-dd HH:mm:ss")}</#if></td> + <td><#if historyEntry.thruDate?exists && historyEntry.thruDate?has_content>${historyEntry.thruDate?string("yyyy-MM-dd HH:mm:ss")}</#if></td> + <td><#if historyEntry.statusId?exists && historyEntry.statusId?has_content>${uiLabelMap.get(historyEntry.statusId)}</#if></td> + <td><#if historyEntry.statusId?exists && historyEntry.statusId == "EXCEL_IMPORTED" && historyEntry.thruReasonId?exists && historyEntry.thruReasonId?has_content>${uiLabelMap.get(historyEntry.thruReasonId)}</#if></td> + <td> + <#assign buttons = 0 /> + <#if historyEntry.logFileName?exists && historyEntry.logFileName?has_content> + <#if Static["org.apache.ofbiz.base.util.FileUtil"].getFile(historyEntry.logFileName).exists()> + <button id="excel-import-log" type="button" onclick="viewExcelImportLog(${historyEntry.sequenceNum});" data-tooltip="${uiLabelMap.ViewExcelImportLogContent}"> + <i class="icon-comments icon-blue">${uiLabelMap.ViewPricatLog}</i> + </button> + <#assign buttons = buttons + 1 /> + </#if> + </#if> + <#if buttons == 0> + <#--- <button id="excel-import-empty" type="button"></button> --> + <#assign buttons = buttons + 1 /> + </#if> + <#if historyEntry.logFileName?exists && historyEntry.logFileName?has_content> + <#if Static["org.apache.ofbiz.pricat.AbstractPricatParser"].isCommentedExcelExists(request, historyEntry.sequenceNum)> + <button id="excel-import-download" type="button" onclick="downloadCommentedExcel(${historyEntry.sequenceNum});" data-tooltip="${uiLabelMap.DownloadCommentedExcel}"> + <i class="icon-download icon-blue">${uiLabelMap.DownloadCommentedPricat}</i> + </button> + <#assign buttons = buttons + 1 /> + </#if> + </#if> + <#if buttons == 1> + <#--- <button id="excel-import-empty" type="button"></button> --> + </#if> + </td> + </tr> + </#list> + <#else> + <tr> + <td colspan="10" style="text-align:center;vertical-align:middle;height:60px;"> + ${uiLabelMap.ExcelImportTipNoData} + </td> + </tr> + </#if> + </tbody> +</table> +<script type="text/javascript" language="JavaScript"> + function viewExcelImportLog(sequenceNum) { + document.location = "<@ofbizUrl>viewExcelImportLog</@ofbizUrl>?sequenceNum=" + sequenceNum; + } + + function downloadCommentedExcel(sequenceNum) { + document.location = "<@ofbizUrl>downloadCommentedExcel</@ofbizUrl>?sequenceNum=" + sequenceNum; + } +</script> \ No newline at end of file |
Free forum by Nabble | Edit this page |