/** * Translates the filter criteria ({@link #addFilterParameter(String, String)}) to a valid HQL * where clause (without the 'where' keyword). After calling this method the method {@link * #getNamedParameters()} can be called. Note that currently only filtering on string and boolean * properties is supported. Also filtering on the identifier of a referenced business object is * supported. * * @return a valid where clause or an empty string if not set. */ public String getWhereClause() { if (whereClause != null) { return whereClause; } // add some default filter parameters filterParameters.put( JsonConstants.QUERY_PARAM_USER, OBContext.getOBContext().getUser().getId()); if (!filterParameters.containsKey(JsonConstants.QUERY_PARAM_CLIENT)) { filterParameters.put( JsonConstants.QUERY_PARAM_CLIENT, OBContext.getOBContext().getUser().getId()); } final SimpleDateFormat simpleDateFormat = JsonUtils.createDateFormat(); Check.isNotNull(entity, "Entity must be set"); final StringBuilder sb = new StringBuilder(); boolean addAnd = false; final StringBuilder orgPart = new StringBuilder(); final List<Property> propertyDone = new ArrayList<Property>(); String whereParameterValue = null; for (String key : filterParameters.keySet()) { String value = filterParameters.get(key); if (key.equals(JsonConstants.WHERE_PARAMETER)) { // there are cases where null is set as a string // handle this if (value.equals("null") || value.length() == 0) { continue; } whereParameterValue = value; continue; } // handle the case that we should filter on the accessible organizations if (key.equals(JsonConstants.ORG_PARAMETER)) { if (entity.isOrganizationEnabled() && value != null && value.length() > 0) { final Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider().getNaturalTree(value); if (orgs.size() > 0) { if (getMainAlias() != null) { orgPart.append(" " + getMainAlias() + ".organization in ("); } else { orgPart.append(" organization in ("); } boolean addComma = false; for (String org : orgs) { if (addComma) { orgPart.append(","); } orgPart.append("'" + org + "'"); addComma = true; } orgPart.append(") "); } } continue; } // determine the property final List<Property> properties = JsonUtils.getPropertiesOnPath(getEntity(), key); if (properties.isEmpty()) { continue; } final Property property = properties.get(properties.size() - 1); // invalid propname, ignore this one // TODO: possibly warn about it if (property == null || propertyDone.contains(property)) { continue; } propertyDone.add(property); // we know the property and the string representation of the value... // do the conversion if (addAnd) { if (doOr) { sb.append(" or "); } else { sb.append(" and "); } } String leftWherePart = null; if (isDoOr()) { leftWherePart = resolveJoins(properties, key); } else if (getMainAlias() != null) { leftWherePart = getMainAlias() + "." + key.trim(); } else { leftWherePart = key; } // get rid of the identifier and replace it with the real property name // or with the concatenation if there are multiple parts // NOTE: the if and else check against the key variable and not the leftwherepart // because the key contains the original string (with the _identifier part). // Within the if the leftWherePart is used because it contains the join aliases if (key.equals(JsonConstants.IDENTIFIER) || key.endsWith("." + JsonConstants.IDENTIFIER)) { // the identifierProperties are read from the owning entity of the // property, that should work fine, as this last property is always part of the // identifier final List<Property> identifierProperties = property.getEntity().getIdentifierProperties(); Check.isTrue( identifierProperties.contains(property), "Property " + property + " not part of identifier of " + property.getEntity()); final String prefix; final int index = leftWherePart.lastIndexOf("."); if (key.equals(JsonConstants.IDENTIFIER)) { prefix = getMainAlias() + "."; } else if (index == -1) { prefix = ""; } else { // the + 1 makes sure that the dot is included prefix = leftWherePart.substring(0, index + 1); } leftWherePart = createIdentifierLeftClause(identifierProperties, prefix); // if the value consists of multiple parts then filtering won't work // only search on the first part then, is pragmatic but very workable if (value != null && value.contains(IdentifierProvider.SEPARATOR)) { final int separatorIndex = value.indexOf(IdentifierProvider.SEPARATOR); value = value.substring(0, separatorIndex); } } // NOTE: If you change this part, make sure that you sync the changes with the // SelectorDataSourceFilter. Check issue https://issues.openbravo.com/view.php?id=14239 // NOTE the typedParameters.add call must be done after the call to // getTypedParameterAlias, this to get the correct alias codes if (key.equals(JsonConstants.IDENTIFIER)) { if (textMatching == TextMatching.exact) { sb.append(leftWherePart + " = " + getTypedParameterAlias()); typedParameters.add(value); } else if (textMatching == TextMatching.startsWith) { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add(escapeLike(value.toUpperCase()) + "%"); } else { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%"); } } else if (!property.isPrimitive()) { // an in parameter use it... if (value.contains(JsonConstants.IN_PARAMETER_SEPARATOR)) { final List<String> values = new ArrayList<String>(); final String[] separatedValues = value.split(JsonConstants.IN_PARAMETER_SEPARATOR); for (String separatedValue : separatedValues) { values.add(separatedValue); } sb.append(leftWherePart + ".id in (" + getTypedParameterAlias() + ")"); typedParameters.add(values); } else { sb.append(leftWherePart + ".id = " + getTypedParameterAlias()); typedParameters.add(value); } } else if (String.class == property.getPrimitiveObjectType()) { if (textMatching == TextMatching.exact) { sb.append(leftWherePart + " = " + getTypedParameterAlias()); typedParameters.add(value); } else if (textMatching == TextMatching.startsWith) { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add(escapeLike(value.toUpperCase()) + "%"); } else { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%"); } } else if (Boolean.class == property.getPrimitiveObjectType()) { final String alias = getTypedParameterAlias(); typedParameters.add(new Boolean(value)); sb.append(leftWherePart + " = " + alias); } else if (property.isNumericType()) { try { final String alias = getTypedParameterAlias(); final BigDecimal bdValue = new BigDecimal(value); if (Long.class == property.getPrimitiveObjectType()) { typedParameters.add(bdValue.longValue()); } else if (Integer.class == property.getPrimitiveObjectType()) { typedParameters.add(bdValue.intValue()); } else { typedParameters.add(bdValue); } sb.append(leftWherePart + " = " + alias); } catch (NumberFormatException e) { // ignore on purpose, incorrect value entered by user // add a dummy whereclause to make the query format correct sb.append(" 1=1 "); } } else if (Date.class.isAssignableFrom(property.getPrimitiveObjectType())) { try { final Calendar cal = Calendar.getInstance(); cal.setTime(simpleDateFormat.parse(value)); final String alias1 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.DATE)); final String alias2 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.MONTH) + 1); final String alias3 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.YEAR)); sb.append( " (day(" + leftWherePart + ") = " + alias1 + " and month(" + leftWherePart + ") = " + alias2 + " and year(" + leftWherePart + ") = " + alias3 + ") "); } catch (Exception e) { // ignore these errors, just don't filter then // add a dummy whereclause to make the query format correct sb.append(" 1=1 "); } // } else if (property.isDate() || property.isDatetime()) { // NOTE: dates arrive in the format of the user.... // sb.append(leftWherePart + " = ?"); // typedParameters.add(value); } else { // TODO: support this.... throw new UnsupportedOperationException( "Type " + property.getPrimitiveObjectType() + " not yet supported for parameter " + key); } addAnd = true; } log.debug("Whereclause for entity " + entity.getName()); log.debug(sb.toString()); for (Object param : typedParameters) { log.debug(param); } log.debug("Textmatching " + textMatching); if (sb.length() == 0) { whereClause = orgPart.length() > 0 ? orgPart.toString() : ""; } else { whereClause = "(" + sb.toString() + ")" + (orgPart.length() > 0 ? " and " + orgPart.toString() : ""); } if (whereParameterValue != null) { if (whereClause.length() > 0) { whereClause = " (" + whereClause + ") and (" + whereParameterValue + ") "; } else { whereClause = " " + whereParameterValue; } } if (whereClause.trim().length() > 0) { whereClause = " where " + whereClause; } // handle special transactional range parameter if (whereClause.contains(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE)) { final String alias = getTypedParameterAlias(); String windowId = RequestContext.get().getRequestParameter("windowId"); if (windowId == null) { windowId = ""; } final String range = Utility.getTransactionalDate( new DalConnectionProvider(false), RequestContext.get().getVariablesSecureApp(), windowId); final int rangeNum = Integer.parseInt(range); final Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1 * rangeNum); whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE, alias); typedParameters.add(cal.getTime()); } if (whereClause.contains(JsonConstants.QUERY_PARAM_CLIENT)) { final String alias = getTypedParameterAlias(); String clientId = (String) DalUtil.getId(OBContext.getOBContext().getCurrentClient()); whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_CLIENT, alias); typedParameters.add(clientId); } whereClause = setRequestParameters(whereClause); whereClause = substituteContextParameters(whereClause); return whereClause; }
private void printPageEdit( HttpServletResponse response, HttpServletRequest request, VariablesSecureApp vars, boolean boolNew, String strC_BP_Group_ID, TableSQLData tableSQL) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: edit"); HashMap<String, String> usedButtonShortCuts; usedButtonShortCuts = new HashMap<String, String>(); String strOrderByFilter = vars.getSessionValue(tabId + "|orderby"); String orderClause = " C_BP_Group.Value"; if (strOrderByFilter == null || strOrderByFilter.equals("")) strOrderByFilter = orderClause; /*{ if (!strOrderByFilter.equals("") && !orderClause.equals("")) strOrderByFilter += ", "; strOrderByFilter += orderClause; }*/ String strCommand = null; BusinessPartnerCategoryData[] data = null; XmlDocument xmlDocument = null; FieldProvider dataField = vars.getEditionData(tabId); vars.removeEditionData(tabId); String strParamName = vars.getSessionValue(tabId + "|paramName"); boolean hasSearchCondition = false; hasSearchCondition = (tableSQL.hasInternalFilter() && ("").equals(strParamName)) || !(("").equals(strParamName) || ("%").equals(strParamName)); String strParamSessionDate = vars.getGlobalVariable( "inpParamSessionDate", Utility.getTransactionalDate(this, vars, windowId), ""); String buscador = ""; String[] discard = {"", "isNotTest"}; if (vars.getSessionValue("#ShowTest", "N").equals("Y")) discard[1] = new String("isTest"); if (dataField == null) { if (!boolNew) { discard[0] = new String("newDiscard"); data = BusinessPartnerCategoryData.selectEdit( this, vars.getSessionValue("#AD_SqlDateTimeFormat"), vars.getLanguage(), strC_BP_Group_ID, Utility.getContext(this, vars, "#User_Client", windowId), Utility.getContext(this, vars, "#AccessibleOrgTree", windowId, accesslevel)); if (!strC_BP_Group_ID.equals("") && (data == null || data.length == 0)) { response.sendRedirect(strDireccion + request.getServletPath() + "?Command=RELATION"); return; } refreshSessionEdit(vars, data); strCommand = "EDIT"; } if (boolNew || data == null || data.length == 0) { discard[0] = new String("editDiscard"); strCommand = "NEW"; data = new BusinessPartnerCategoryData[0]; } else { discard[0] = new String("newDiscard"); } } else { if (dataField.getField("cBpGroupId") == null || dataField.getField("cBpGroupId").equals("")) { discard[0] = new String("editDiscard"); strCommand = "NEW"; boolNew = true; } else { discard[0] = new String("newDiscard"); strCommand = "EDIT"; } } if (dataField == null) { if (boolNew || data == null || data.length == 0) { refreshSessionNew(vars); data = BusinessPartnerCategoryData.set( "", Utility.getDefault( this, vars, "AD_Client_ID", "@AD_CLIENT_ID@", "192", "", dataField), Utility.getDefault(this, vars, "AD_Org_ID", "@AD_Org_ID@", "192", "", dataField), "Y", Utility.getDefault(this, vars, "CreatedBy", "", "192", "", dataField), BusinessPartnerCategoryData.selectDef4966_0( this, Utility.getDefault(this, vars, "CreatedBy", "", "192", "", dataField)), Utility.getDefault(this, vars, "UpdatedBy", "", "192", "", dataField), BusinessPartnerCategoryData.selectDef4968_1( this, Utility.getDefault(this, vars, "UpdatedBy", "", "192", "", dataField)), Utility.getDefault(this, vars, "Value", "", "192", "", dataField), Utility.getDefault(this, vars, "Name", "", "192", "", dataField), Utility.getDefault(this, vars, "Description", "", "192", "", dataField), Utility.getDefault(this, vars, "IsDefault", "", "192", "N", dataField)); } } String currentOrg = (boolNew ? "" : (dataField != null ? dataField.getField("adOrgId") : data[0].getField("adOrgId"))); if (!currentOrg.equals("") && !currentOrg.startsWith("'")) currentOrg = "'" + currentOrg + "'"; String currentClient = (boolNew ? "" : (dataField != null ? dataField.getField("adClientId") : data[0].getField("adClientId"))); if (!currentClient.equals("") && !currentClient.startsWith("'")) currentClient = "'" + currentClient + "'"; boolean hasReadOnlyAccess = org.openbravo.erpCommon.utility.WindowAccessData.hasReadOnlyAccess( this, vars.getRole(), tabId); boolean editableTab = (!hasReadOnlyAccess && (currentOrg.equals("") || Utility.isElementInList( Utility.getContext(this, vars, "#User_Org", windowId, accesslevel), currentOrg)) && (currentClient.equals("") || Utility.isElementInList( Utility.getContext(this, vars, "#User_Client", windowId, accesslevel), currentClient))); if (editableTab) xmlDocument = xmlEngine .readXmlTemplate( "org/openbravo/erpWindows/BusinessPartnerCategory/BusinessPartnerCategory_Edition", discard) .createXmlDocument(); else xmlDocument = xmlEngine .readXmlTemplate( "org/openbravo/erpWindows/BusinessPartnerCategory/BusinessPartnerCategory_NonEditable", discard) .createXmlDocument(); xmlDocument.setParameter("tabId", tabId); ToolBar toolbar = new ToolBar( this, editableTab, vars.getLanguage(), "BusinessPartnerCategory", (strCommand.equals("NEW") || boolNew || (dataField == null && (data == null || data.length == 0))), "document.frmMain.inpcBpGroupId", "", "..", "".equals("Y"), "BusinessPartnerCategory", strReplaceWith, true, false, false, Utility.hasTabAttachments(this, vars, tabId, strC_BP_Group_ID), !hasReadOnlyAccess); toolbar.setTabId(tabId); toolbar.setDeleteable(true); toolbar.prepareEditionTemplate( "N".equals("Y"), hasSearchCondition, vars.getSessionValue("#ShowTest", "N").equals("Y"), "STD", Utility.getContext(this, vars, "ShowAudit", windowId).equals("Y")); xmlDocument.setParameter("toolbar", toolbar.toString()); // set updated timestamp to manage locking mechanism if (!boolNew) { xmlDocument.setParameter( "updatedTimestamp", (dataField != null ? dataField.getField("updatedTimeStamp") : data[0].getField("updatedTimeStamp"))); } boolean concurrentSave = vars.getSessionValue(tabId + "|concurrentSave").equals("true"); if (concurrentSave) { // after concurrent save error, force autosave xmlDocument.setParameter("autosave", "Y"); } else { xmlDocument.setParameter("autosave", "N"); } vars.removeSessionValue(tabId + "|concurrentSave"); try { WindowTabs tabs = new WindowTabs(this, vars, tabId, windowId, true, (strCommand.equalsIgnoreCase("NEW"))); xmlDocument.setParameter("parentTabContainer", tabs.parentTabs()); xmlDocument.setParameter("mainTabContainer", tabs.mainTabs()); // if (!strC_BP_Group_ID.equals("")) xmlDocument.setParameter("childTabContainer", // tabs.childTabs(false)); // else xmlDocument.setParameter("childTabContainer", tabs.childTabs(true)); xmlDocument.setParameter("childTabContainer", tabs.childTabs(false)); String hideBackButton = vars.getGlobalVariable("hideMenu", "#Hide_BackButton", ""); NavigationBar nav = new NavigationBar( this, vars.getLanguage(), "BusinessPartnerCategory_Relation.html", "BusinessPartnerCategory", "W", strReplaceWith, tabs.breadcrumb(), hideBackButton.equals("true"), !concurrentSave); xmlDocument.setParameter("navigationBar", nav.toString()); LeftTabsBar lBar = new LeftTabsBar( this, vars.getLanguage(), "BusinessPartnerCategory_Relation.html", strReplaceWith); xmlDocument.setParameter("leftTabs", lBar.editionTemplate(strCommand.equals("NEW"))); } catch (Exception ex) { throw new ServletException(ex); } xmlDocument.setParameter("commandType", strCommand); xmlDocument.setParameter("buscador", buscador); xmlDocument.setParameter("windowId", windowId); xmlDocument.setParameter("changed", ""); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); final String strMappingName = Utility.getTabURL(tabId, "E", false); xmlDocument.setParameter("mappingName", strMappingName); xmlDocument.setParameter("confirmOnChanges", Utility.getJSConfirmOnChanges(vars, windowId)); // xmlDocument.setParameter("buttonReference", Utility.messageBD(this, "Reference", // vars.getLanguage())); xmlDocument.setParameter("paramSessionDate", strParamSessionDate); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); OBError myMessage = vars.getMessage(tabId); vars.removeMessage(tabId); if (myMessage != null) { xmlDocument.setParameter("messageType", myMessage.getType()); xmlDocument.setParameter("messageTitle", myMessage.getTitle()); xmlDocument.setParameter("messageMessage", myMessage.getMessage()); } xmlDocument.setParameter("displayLogic", getDisplayLogicContext(vars, boolNew)); if (dataField == null) { xmlDocument.setData("structure1", data); } else { FieldProvider[] dataAux = new FieldProvider[1]; dataAux[0] = dataField; xmlDocument.setData("structure1", dataAux); } try { ComboTableData comboTableData = null; String userOrgList = ""; if (editableTab) userOrgList = Utility.getContext(this, vars, "#User_Org", windowId, accesslevel); // editable record else userOrgList = currentOrg; comboTableData = new ComboTableData( vars, this, "19", "AD_Org_ID", "", "", userOrgList, Utility.getContext(this, vars, "#User_Client", windowId), 0); Utility.fillSQLParameters( this, vars, (dataField == null ? data[0] : dataField), comboTableData, windowId, (dataField == null ? data[0].getField("adOrgId") : dataField.getField("adOrgId"))); xmlDocument.setData( "reportAD_Org_ID", "liststructure", comboTableData.select(!strCommand.equals("NEW"))); comboTableData = null; xmlDocument.setParameter("Created_Format", vars.getSessionValue("#AD_SqlDateTimeFormat")); xmlDocument.setParameter( "Created_Maxlength", Integer.toString(vars.getSessionValue("#AD_SqlDateTimeFormat").length())); xmlDocument.setParameter("Updated_Format", vars.getSessionValue("#AD_SqlDateTimeFormat")); xmlDocument.setParameter( "Updated_Maxlength", Integer.toString(vars.getSessionValue("#AD_SqlDateTimeFormat").length())); } catch (Exception ex) { ex.printStackTrace(); throw new ServletException(ex); } xmlDocument.setParameter("scriptOnLoad", getShortcutScript(usedButtonShortCuts)); final String refererURL = vars.getSessionValue(tabId + "|requestURL"); vars.removeSessionValue(tabId + "|requestURL"); if (!refererURL.equals("")) { final Boolean failedAutosave = (Boolean) vars.getSessionObject(tabId + "|failedAutosave"); vars.removeSessionValue(tabId + "|failedAutosave"); if (failedAutosave != null && failedAutosave) { final String jsFunction = "continueUserAction('" + refererURL + "');"; xmlDocument.setParameter("failedAutosave", jsFunction); } } if (strCommand.equalsIgnoreCase("NEW")) { vars.removeSessionValue(tabId + "|failedAutosave"); vars.removeSessionValue(strMappingName + "|hash"); } response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); }