Beispiel #1
0
 public static GenericValue findParty(
     Delegator delegator, String idToFind, String partyIdentificationTypeId)
     throws GenericEntityException {
   List<GenericValue> parties = findPartiesById(delegator, idToFind, partyIdentificationTypeId);
   GenericValue party = EntityUtil.getFirst(parties);
   return party;
 }
Beispiel #2
0
  public static GenericValue getPaymentAddress(Delegator delegator, String partyId) {
    List<GenericValue> paymentAddresses = null;
    try {
      paymentAddresses =
          delegator.findByAnd(
              "PartyContactMechPurpose",
              UtilMisc.toMap("partyId", partyId, "contactMechPurposeTypeId", "PAYMENT_LOCATION"),
              UtilMisc.toList("-fromDate"));
      paymentAddresses = EntityUtil.filterByDate(paymentAddresses);
    } catch (GenericEntityException e) {
      Debug.logError(e, "Trouble getting PartyContactMechPurpose entity list", module);
    }

    // get the address for the primary contact mech
    GenericValue purpose = EntityUtil.getFirst(paymentAddresses);
    GenericValue postalAddress = null;
    if (purpose != null) {
      try {
        postalAddress =
            delegator.findByPrimaryKey(
                "PostalAddress",
                UtilMisc.toMap("contactMechId", purpose.getString("contactMechId")));
      } catch (GenericEntityException e) {
        Debug.logError(
            e,
            "Trouble getting PostalAddress record for contactMechId: "
                + purpose.getString("contactMechId"),
            module);
      }
    }

    return postalAddress;
  }
Beispiel #3
0
  public static String[] findFirstMatchingPartyAndContactMechId(
      Delegator delegator,
      String address1,
      String address2,
      String city,
      String stateProvinceGeoId,
      String postalCode,
      String postalCodeExt,
      String countryGeoId,
      String firstName,
      String middleName,
      String lastName)
      throws GeneralException {

    List<GenericValue> matching =
        findMatchingPersonPostalAddresses(
            delegator,
            address1,
            address2,
            city,
            stateProvinceGeoId,
            postalCode,
            postalCodeExt,
            countryGeoId,
            firstName,
            middleName,
            lastName);
    GenericValue v = EntityUtil.getFirst(matching);
    if (v != null) {
      return new String[] {v.getString("partyId"), v.getString("contactMechId")};
    }
    return null;
  }
  /**
   * Finds or creates a specialized (auto-save) shopping list used to record shopping bag contents
   * between user visits.
   */
  public static String getAutoSaveListId(
      Delegator delegator,
      LocalDispatcher dispatcher,
      String partyId,
      GenericValue userLogin,
      String productStoreId)
      throws GenericEntityException, GenericServiceException {
    if (partyId == null && userLogin != null) {
      partyId = userLogin.getString("partyId");
    }

    String autoSaveListId = null;
    GenericValue list = null;
    // TODO: add sorting, just in case there are multiple...
    if (partyId != null) {
      Map<String, Object> findMap =
          UtilMisc.<String, Object>toMap(
              "partyId",
              partyId,
              "productStoreId",
              productStoreId,
              "shoppingListTypeId",
              "SLT_SPEC_PURP",
              "listName",
              PERSISTANT_LIST_NAME);
      List<GenericValue> existingLists =
          EntityQuery.use(delegator).from("ShoppingList").where(findMap).queryList();
      Debug.logInfo(
          "Finding existing auto-save shopping list with:  \nfindMap: "
              + findMap
              + "\nlists: "
              + existingLists,
          module);

      if (UtilValidate.isNotEmpty(existingLists)) {
        list = EntityUtil.getFirst(existingLists);
        autoSaveListId = list.getString("shoppingListId");
      }
    }
    if (list == null && dispatcher != null) {
      Map<String, Object> listFields =
          UtilMisc.<String, Object>toMap(
              "userLogin",
              userLogin,
              "productStoreId",
              productStoreId,
              "shoppingListTypeId",
              "SLT_SPEC_PURP",
              "listName",
              PERSISTANT_LIST_NAME);
      Map<String, Object> newListResult = dispatcher.runSync("createShoppingList", listFields);

      if (newListResult != null) {
        autoSaveListId = (String) newListResult.get("shoppingListId");
      }
    }

    return autoSaveListId;
  }
  /**
   * Retrieves a single user preference from persistent storage. Call with userPrefTypeId and
   * optional userPrefLoginId. If userPrefLoginId isn't specified, then the currently logged-in
   * user's userLoginId will be used. The retrieved preference is contained in the
   * <b>userPrefMap</b> element.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> getUserPreference(DispatchContext ctx, Map<String, ?> context) {
    Locale locale = (Locale) context.get("locale");
    if (!PreferenceWorker.isValidGetId(ctx, context)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.permissionError", locale));
    }
    Delegator delegator = ctx.getDelegator();

    String userPrefTypeId = (String) context.get("userPrefTypeId");
    if (UtilValidate.isEmpty(userPrefTypeId)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.invalidArgument", locale));
    }
    String userLoginId = PreferenceWorker.getUserLoginId(context, true);
    Map<String, String> fieldMap =
        UtilMisc.toMap("userLoginId", userLoginId, "userPrefTypeId", userPrefTypeId);
    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    if (UtilValidate.isNotEmpty(userPrefGroupTypeId)) {
      fieldMap.put("userPrefGroupTypeId", userPrefGroupTypeId);
    }

    Map<String, Object> userPrefMap = null;
    try {
      GenericValue preference =
          EntityUtil.getFirst(delegator.findByAnd("UserPreference", fieldMap));
      if (preference != null) {
        userPrefMap = PreferenceWorker.createUserPrefMap(preference);
      }
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    } catch (GeneralException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    }

    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("userPrefMap", userPrefMap);
    if (userPrefMap != null) {
      // Put the value in the result Map too, makes access easier for calling methods.
      Object userPrefValue = userPrefMap.get(userPrefTypeId);
      if (userPrefValue != null) {
        result.put("userPrefValue", userPrefValue);
      }
    }
    return result;
  }
Beispiel #6
0
 public static GenericValue findPartyLatestUserLogin(String partyId, Delegator delegator) {
   try {
     List<GenericValue> userLoginList =
         delegator.findByAnd(
             "UserLogin",
             UtilMisc.toMap("partyId", partyId),
             UtilMisc.toList("-" + ModelEntity.STAMP_FIELD));
     return EntityUtil.getFirst(userLoginList);
   } catch (GenericEntityException e) {
     Debug.logError(
         e,
         "Error while finding latest UserLogin for party with ID ["
             + partyId
             + "]: "
             + e.toString(),
         module);
     return null;
   }
 }
Beispiel #7
0
 public static Timestamp findPartyLastLoginTime(String partyId, Delegator delegator) {
   try {
     List<GenericValue> loginHistory =
         delegator.findByAnd(
             "UserLoginHistory", UtilMisc.toMap("partyId", partyId), UtilMisc.toList("-fromDate"));
     GenericValue v = EntityUtil.getFirst(loginHistory);
     if (v != null) {
       return v.getTimestamp("fromDate");
     } else {
       return null;
     }
   } catch (GenericEntityException e) {
     Debug.logError(
         e,
         "Error while finding latest login time for party with ID ["
             + partyId
             + "]: "
             + e.toString(),
         module);
     return null;
   }
 }
Beispiel #8
0
 public static GenericValue findPartyLatestContactMech(
     String partyId, String contactMechTypeId, Delegator delegator) {
   try {
     List<GenericValue> cmList =
         delegator.findByAnd(
             "PartyAndContactMech",
             UtilMisc.toMap("partyId", partyId, "contactMechTypeId", contactMechTypeId),
             UtilMisc.toList("-fromDate"));
     cmList = EntityUtil.filterByDate(cmList);
     return EntityUtil.getFirst(cmList);
   } catch (GenericEntityException e) {
     Debug.logError(
         e,
         "Error while finding latest ContactMech for party with ID ["
             + partyId
             + "] TYPE ["
             + contactMechTypeId
             + "]: "
             + e.toString(),
         module);
     return null;
   }
 }
Beispiel #9
0
  public static Map<String, Object> assembleCrmsfaShipmentFormMergeContext(
      Delegator delegator,
      String orderId,
      String shipGroupSeqId,
      String shipmentId,
      Locale locale) {
    Map<String, Object> templateContext = new HashMap<String, Object>();

    try {

      // Prefer shipment data if shipmentId is provided
      if (UtilValidate.isNotEmpty(shipmentId)) {

        GenericValue shipment =
            delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
        if (UtilValidate.isNotEmpty(shipment)) {

          GenericValue shipLoc = shipment.getRelatedOne("DestinationPostalAddress");
          if (UtilValidate.isNotEmpty(shipLoc)) {
            templateContext.put("orderShippingAddress1", shipLoc.get("address1"));
            templateContext.put("orderShippingAddress2", shipLoc.get("address2"));
            templateContext.put("orderShippingCity", shipLoc.get("city"));
            templateContext.put("orderShippingPostalCode", shipLoc.get("postalCode"));

            GenericValue stateProvGeo = shipLoc.getRelatedOne("StateProvinceGeo");
            if (UtilValidate.isNotEmpty(stateProvGeo)) {
              templateContext.put("orderShippingStateProvince", stateProvGeo.get("geoName"));
            }
            GenericValue countryGeo = shipLoc.getRelatedOne("CountryGeo");
            if (UtilValidate.isNotEmpty(countryGeo)) {
              templateContext.put("orderShippingCountry", countryGeo.get("geoName"));
            }
          }

          GenericValue phoneNumber = shipment.getRelatedOne("DestinationTelecomNumber");
          if (UtilValidate.isNotEmpty(phoneNumber)) {

            String phoneNumberString =
                UtilValidate.isEmpty(phoneNumber.getString("countryCode"))
                    ? ""
                    : phoneNumber.getString("countryCode") + " ";
            if (UtilValidate.isNotEmpty(phoneNumber.getString("areaCode"))) {
              phoneNumberString += phoneNumber.getString("areaCode") + " ";
            }
            if (UtilValidate.isNotEmpty(phoneNumber.getString("contactNumber"))) {
              phoneNumberString += phoneNumber.getString("contactNumber");
            }
            templateContext.put("orderShippingPhone", phoneNumberString);
          }

          GenericValue statusItem = shipment.getRelatedOne("StatusItem");
          if (UtilValidate.isNotEmpty(statusItem)) {
            templateContext.put("shipmentStatus", statusItem.get("description", locale));
          }
        }

      } else if (UtilValidate.isNotEmpty(orderId)) {

        OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
        GenericValue shipGroup = orh.getOrderItemShipGroup(shipGroupSeqId);
        if (UtilValidate.isEmpty(shipGroup)) {

          // Default to the first ship group if no shipGroupSeqId is provided
          List shipGroups = orh.getOrderItemShipGroups();
          if (UtilValidate.isNotEmpty(shipGroups)) {
            shipGroup = (GenericValue) shipGroups.get(0);
          }
        }

        if (UtilValidate.isNotEmpty(shipGroup)) {
          GenericValue shipLoc = shipGroup.getRelatedOne("PostalAddress");
          if (UtilValidate.isNotEmpty(shipLoc)) {
            templateContext.put("orderShippingAddress1", shipLoc.get("address1"));
            templateContext.put("orderShippingAddress2", shipLoc.get("address2"));
            templateContext.put("orderShippingCity", shipLoc.get("city"));
            templateContext.put("orderShippingPostalCode", shipLoc.get("postalCode"));

            GenericValue stateProvGeo = shipLoc.getRelatedOne("StateProvinceGeo");
            if (UtilValidate.isNotEmpty(stateProvGeo)) {
              templateContext.put("orderShippingStateProvince", stateProvGeo.get("geoName"));
            }
            GenericValue countryGeo = shipLoc.getRelatedOne("CountryGeo");
            if (UtilValidate.isNotEmpty(countryGeo)) {
              templateContext.put("orderShippingCountry", countryGeo.get("geoName"));
            }
          }

          GenericValue phoneNumber = shipGroup.getRelatedOne("TelecomTelecomNumber");
          if (UtilValidate.isNotEmpty(phoneNumber)) {

            String phoneNumberString =
                UtilValidate.isEmpty(phoneNumber.getString("countryCode"))
                    ? ""
                    : phoneNumber.getString("countryCode") + " ";
            if (UtilValidate.isNotEmpty(phoneNumber.getString("areaCode"))) {
              phoneNumberString += phoneNumber.getString("areaCode") + " ";
            }
            if (UtilValidate.isNotEmpty(phoneNumber.getString("contactNumber"))) {
              phoneNumberString += phoneNumber.getString("contactNumber");
            }
            templateContext.put("orderShippingPhone", phoneNumberString);
          }

          // Find any shipments relating to this ship group
          List<GenericValue> shipments =
              delegator.findByAnd(
                  "Shipment",
                  UtilMisc.toMap(
                      "primaryOrderId",
                      orderId,
                      "primaryShipGroupSeqId",
                      shipGroup.getString("shipGroupSeqId")),
                  UtilMisc.toList("createdStamp DESC"));
          GenericValue shipment = EntityUtil.getFirst(shipments);
          if (UtilValidate.isNotEmpty(shipment)) {
            GenericValue statusItem = shipment.getRelatedOne("StatusItem");
            if (UtilValidate.isNotEmpty(statusItem)) {
              templateContext.put("shipmentStatus", statusItem.get("description", locale));
            }
          }
        }
      }
    } catch (GenericEntityException e) {
      Debug.logError(e, MODULE);
    }
    return templateContext;
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    Delegator delegator =
        (Delegator) httpRequest.getSession().getServletContext().getAttribute("delegator");

    // Get ServletContext
    ServletContext servletContext = config.getServletContext();

    ContextFilter.setCharacterEncoding(request);

    // Set request attribute and session
    UrlServletHelper.setRequestAttributes(request, delegator, servletContext);

    // set initial parameters
    String initDefaultLocalesString = config.getInitParameter("defaultLocaleString");
    String initRedirectUrl = config.getInitParameter("redirectUrl");
    defaultLocaleString =
        UtilValidate.isNotEmpty(initDefaultLocalesString) ? initDefaultLocalesString : "";
    redirectUrl = UtilValidate.isNotEmpty(initRedirectUrl) ? initRedirectUrl : "";

    String pathInfo = httpRequest.getServletPath();
    if (UtilValidate.isNotEmpty(pathInfo)) {
      List<String> pathElements = StringUtil.split(pathInfo, "/");
      String alternativeUrl = pathElements.get(0);

      String productId = null;
      String productCategoryId = null;
      String urlContentId = null;
      try {
        // look for productId
        if (alternativeUrl.endsWith("-p")) {
          List<EntityCondition> productContentConds = FastList.newInstance();
          productContentConds.add(
              EntityCondition.makeCondition("productContentTypeId", "ALTERNATIVE_URL"));
          productContentConds.add(EntityUtil.getFilterByDateExpr());
          List<GenericValue> productContentInfos =
              EntityQuery.use(delegator)
                  .from("ProductContentAndInfo")
                  .where(productContentConds)
                  .orderBy("-fromDate")
                  .cache(true)
                  .queryList();
          if (UtilValidate.isNotEmpty(productContentInfos)) {
            for (GenericValue productContentInfo : productContentInfos) {
              String contentId = (String) productContentInfo.get("contentId");
              List<GenericValue> ContentAssocDataResourceViewTos =
                  EntityQuery.use(delegator)
                      .from("ContentAssocDataResourceViewTo")
                      .where(
                          "contentIdStart",
                          contentId,
                          "caContentAssocTypeId",
                          "ALTERNATE_LOCALE",
                          "drDataResourceTypeId",
                          "ELECTRONIC_TEXT")
                      .cache(true)
                      .queryList();
              if (UtilValidate.isNotEmpty(ContentAssocDataResourceViewTos)) {
                for (GenericValue ContentAssocDataResourceViewTo :
                    ContentAssocDataResourceViewTos) {
                  GenericValue ElectronicText =
                      ContentAssocDataResourceViewTo.getRelatedOne("ElectronicText", true);
                  if (UtilValidate.isNotEmpty(ElectronicText)) {
                    String textData = (String) ElectronicText.get("textData");
                    textData = UrlServletHelper.invalidCharacter(textData);
                    if (alternativeUrl.matches(textData + ".+$")) {
                      String productIdStr = null;
                      productIdStr = alternativeUrl.replace(textData + "-", "");
                      productIdStr = productIdStr.replace("-p", "");
                      String checkProductId = (String) productContentInfo.get("productId");
                      if (productIdStr.equalsIgnoreCase(checkProductId)) {
                        productId = checkProductId;
                        break;
                      }
                    }
                  }
                }
              }
              if (UtilValidate.isEmpty(productId)) {
                List<GenericValue> contentDataResourceViews =
                    EntityQuery.use(delegator)
                        .from("ContentDataResourceView")
                        .where("contentId", contentId, "drDataResourceTypeId", "ELECTRONIC_TEXT")
                        .cache(true)
                        .queryList();
                for (GenericValue contentDataResourceView : contentDataResourceViews) {
                  GenericValue ElectronicText =
                      contentDataResourceView.getRelatedOne("ElectronicText", true);
                  if (UtilValidate.isNotEmpty(ElectronicText)) {
                    String textData = (String) ElectronicText.get("textData");
                    if (UtilValidate.isNotEmpty(textData)) {
                      textData = UrlServletHelper.invalidCharacter(textData);
                      if (alternativeUrl.matches(textData + ".+$")) {
                        String productIdStr = null;
                        productIdStr = alternativeUrl.replace(textData + "-", "");
                        productIdStr = productIdStr.replace("-p", "");
                        String checkProductId = (String) productContentInfo.get("productId");
                        if (productIdStr.equalsIgnoreCase(checkProductId)) {
                          productId = checkProductId;
                          break;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }

        // look for productCategoryId
        if (alternativeUrl.endsWith("-c")) {
          List<EntityCondition> productCategoryContentConds = FastList.newInstance();
          productCategoryContentConds.add(
              EntityCondition.makeCondition("prodCatContentTypeId", "ALTERNATIVE_URL"));
          productCategoryContentConds.add(EntityUtil.getFilterByDateExpr());
          List<GenericValue> productCategoryContentInfos =
              EntityQuery.use(delegator)
                  .from("ProductCategoryContentAndInfo")
                  .where(productCategoryContentConds)
                  .orderBy("-fromDate")
                  .cache(true)
                  .queryList();
          if (UtilValidate.isNotEmpty(productCategoryContentInfos)) {
            for (GenericValue productCategoryContentInfo : productCategoryContentInfos) {
              String contentId = (String) productCategoryContentInfo.get("contentId");
              List<GenericValue> ContentAssocDataResourceViewTos =
                  EntityQuery.use(delegator)
                      .from("ContentAssocDataResourceViewTo")
                      .where(
                          "contentIdStart",
                          contentId,
                          "caContentAssocTypeId",
                          "ALTERNATE_LOCALE",
                          "drDataResourceTypeId",
                          "ELECTRONIC_TEXT")
                      .cache(true)
                      .queryList();
              if (UtilValidate.isNotEmpty(ContentAssocDataResourceViewTos)) {
                for (GenericValue ContentAssocDataResourceViewTo :
                    ContentAssocDataResourceViewTos) {
                  GenericValue ElectronicText =
                      ContentAssocDataResourceViewTo.getRelatedOne("ElectronicText", true);
                  if (UtilValidate.isNotEmpty(ElectronicText)) {
                    String textData = (String) ElectronicText.get("textData");
                    if (UtilValidate.isNotEmpty(textData)) {
                      textData = UrlServletHelper.invalidCharacter(textData);
                      if (alternativeUrl.matches(textData + ".+$")) {
                        String productCategoryStr = null;
                        productCategoryStr = alternativeUrl.replace(textData + "-", "");
                        productCategoryStr = productCategoryStr.replace("-c", "");
                        String checkProductCategoryId =
                            (String) productCategoryContentInfo.get("productCategoryId");
                        if (productCategoryStr.equalsIgnoreCase(checkProductCategoryId)) {
                          productCategoryId = checkProductCategoryId;
                          break;
                        }
                      }
                    }
                  }
                }
              }
              if (UtilValidate.isEmpty(productCategoryId)) {
                List<GenericValue> contentDataResourceViews =
                    EntityQuery.use(delegator)
                        .from("ContentDataResourceView")
                        .where("contentId", contentId, "drDataResourceTypeId", "ELECTRONIC_TEXT")
                        .cache(true)
                        .queryList();
                for (GenericValue contentDataResourceView : contentDataResourceViews) {
                  GenericValue ElectronicText =
                      contentDataResourceView.getRelatedOne("ElectronicText", true);
                  if (UtilValidate.isNotEmpty(ElectronicText)) {
                    String textData = (String) ElectronicText.get("textData");
                    if (UtilValidate.isNotEmpty(textData)) {
                      textData = UrlServletHelper.invalidCharacter(textData);
                      if (alternativeUrl.matches(textData + ".+$")) {
                        String productCategoryStr = null;
                        productCategoryStr = alternativeUrl.replace(textData + "-", "");
                        productCategoryStr = productCategoryStr.replace("-c", "");
                        String checkProductCategoryId =
                            (String) productCategoryContentInfo.get("productCategoryId");
                        if (productCategoryStr.equalsIgnoreCase(checkProductCategoryId)) {
                          productCategoryId = checkProductCategoryId;
                          break;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }

      } catch (GenericEntityException e) {
        Debug.logWarning("Cannot look for product and product category", module);
      }

      // generate forward URL
      StringBuilder urlBuilder = new StringBuilder();
      urlBuilder.append("/" + CONTROL_MOUNT_POINT);

      if (UtilValidate.isNotEmpty(productId)) {
        try {
          List<EntityCondition> conds = FastList.newInstance();
          conds.add(EntityCondition.makeCondition("productId", productId));
          conds.add(EntityUtil.getFilterByDateExpr());
          List<GenericValue> productCategoryMembers =
              EntityQuery.use(delegator)
                  .select("productCategoryId")
                  .from("ProductCategoryMember")
                  .where(conds)
                  .orderBy("-fromDate")
                  .cache(true)
                  .queryList();
          if (UtilValidate.isNotEmpty(productCategoryMembers)) {
            GenericValue productCategoryMember = EntityUtil.getFirst(productCategoryMembers);
            productCategoryId = productCategoryMember.getString("productCategoryId");
          }
        } catch (GenericEntityException e) {
          Debug.logError(e, "Cannot find product category for product: " + productId, module);
        }
        urlBuilder.append("/" + PRODUCT_REQUEST);

      } else {
        urlBuilder.append("/" + CATEGORY_REQUEST);
      }

      // generate trail belong to a top category
      String topCategoryId = CategoryWorker.getCatalogTopCategory(httpRequest, null);
      List<GenericValue> trailCategories =
          CategoryWorker.getRelatedCategoriesRet(
              httpRequest, "trailCategories", topCategoryId, false, false, true);
      List<String> trailCategoryIds =
          EntityUtil.getFieldListFromEntityList(trailCategories, "productCategoryId", true);

      // look for productCategoryId from productId
      if (UtilValidate.isNotEmpty(productId)) {
        try {
          List<EntityCondition> rolllupConds = FastList.newInstance();
          rolllupConds.add(EntityCondition.makeCondition("productId", productId));
          rolllupConds.add(EntityUtil.getFilterByDateExpr());
          List<GenericValue> productCategoryMembers =
              EntityQuery.use(delegator)
                  .from("ProductCategoryMember")
                  .where(rolllupConds)
                  .orderBy("-fromDate")
                  .cache(true)
                  .queryList();
          for (GenericValue productCategoryMember : productCategoryMembers) {
            String trailCategoryId = productCategoryMember.getString("productCategoryId");
            if (trailCategoryIds.contains(trailCategoryId)) {
              productCategoryId = trailCategoryId;
              break;
            }
          }
        } catch (GenericEntityException e) {
          Debug.logError(e, "Cannot generate trail from product category", module);
        }
      }

      // generate trail elements from productCategoryId
      if (UtilValidate.isNotEmpty(productCategoryId)) {
        List<String> trailElements = FastList.newInstance();
        trailElements.add(productCategoryId);
        String parentProductCategoryId = productCategoryId;
        while (UtilValidate.isNotEmpty(parentProductCategoryId)) {
          // find product category rollup
          try {
            List<EntityCondition> rolllupConds = FastList.newInstance();
            rolllupConds.add(
                EntityCondition.makeCondition("productCategoryId", parentProductCategoryId));
            rolllupConds.add(EntityUtil.getFilterByDateExpr());
            List<GenericValue> productCategoryRollups =
                EntityQuery.use(delegator)
                    .from("ProductCategoryRollup")
                    .where(rolllupConds)
                    .orderBy("-fromDate")
                    .cache(true)
                    .queryList();
            if (UtilValidate.isNotEmpty(productCategoryRollups)) {
              // add only categories that belong to the top category to trail
              for (GenericValue productCategoryRollup : productCategoryRollups) {
                String trailCategoryId = productCategoryRollup.getString("parentProductCategoryId");
                parentProductCategoryId = trailCategoryId;
                if (trailCategoryIds.contains(trailCategoryId)) {
                  trailElements.add(trailCategoryId);
                  break;
                }
              }
            } else {
              parentProductCategoryId = null;
            }
          } catch (GenericEntityException e) {
            Debug.logError(e, "Cannot generate trail from product category", module);
          }
        }
        Collections.reverse(trailElements);

        List<String> trail = CategoryWorker.getTrail(httpRequest);
        if (trail == null) {
          trail = FastList.newInstance();
        }

        // adjust trail
        String previousCategoryId = null;
        if (trail.size() > 0) {
          previousCategoryId = trail.get(trail.size() - 1);
        }
        trail = CategoryWorker.adjustTrail(trail, productCategoryId, previousCategoryId);

        if (trailElements.size() == 1) {
          CategoryWorker.setTrail(request, trailElements.get(0), null);
        } else if (trailElements.size() == 2) {
          CategoryWorker.setTrail(request, trailElements.get(1), trailElements.get(0));
        } else if (trailElements.size() > 2) {
          if (trail.contains(trailElements.get(0))) {
            // first category is in the trail, so remove it everything after that and fill it in
            // with the list from the pathInfo
            int firstElementIndex = trail.indexOf(trailElements.get(0));
            while (trail.size() > firstElementIndex) {
              trail.remove(firstElementIndex);
            }
            trail.addAll(trailElements);
          } else {
            // first category is NOT in the trail, so clear out the trail and use the trailElements
            // list
            trail.clear();
            trail.addAll(trailElements);
          }
          CategoryWorker.setTrail(request, trail);
        }

        request.setAttribute("productCategoryId", productCategoryId);

        if (productId != null) {
          request.setAttribute("product_id", productId);
          request.setAttribute("productId", productId);
        }
      }

      // Set view query parameters
      UrlServletHelper.setViewQueryParameters(request, urlBuilder);
      if (UtilValidate.isNotEmpty(productId)
          || UtilValidate.isNotEmpty(productCategoryId)
          || UtilValidate.isNotEmpty(urlContentId)) {
        Debug.logInfo("[Filtered request]: " + pathInfo + " (" + urlBuilder + ")", module);
        ContextFilter.setAttributesFromRequestBody(request);
        RequestDispatcher dispatch = request.getRequestDispatcher(urlBuilder.toString());
        dispatch.forward(request, response);
        return;
      }

      // Check path alias
      UrlServletHelper.checkPathAlias(request, httpResponse, delegator, pathInfo);
    }

    // we're done checking; continue on
    chain.doFilter(request, response);
  }
  /**
   * Creates and updates a PartyRelationship creating related PartyRoles if needed. A side of the
   * relationship is checked to maintain history
   *
   * @param ctx The DispatchContext that this service is operating in
   * @param context Map containing the input parameters
   * @return Map with the result of the service, the output parameters
   */
  public static Map<String, Object> createUpdatePartyRelationshipAndRoles(
      DispatchContext ctx, Map<String, ? extends Object> context) {
    Map<String, Object> result = FastMap.newInstance();
    Delegator delegator = ctx.getDelegator();
    LocalDispatcher dispatcher = ctx.getDispatcher();

    try {
      List<GenericValue> partyRelationShipList =
          PartyRelationshipHelper.getActivePartyRelationships(delegator, context);
      if (UtilValidate.isEmpty(
          partyRelationShipList)) { // If already exists and active nothing to do: keep the current
                                    // one
        String partyId = (String) context.get("partyId");
        String partyIdFrom = (String) context.get("partyIdFrom");
        String partyIdTo = (String) context.get("partyIdTo");
        String roleTypeIdFrom = (String) context.get("roleTypeIdFrom");
        String roleTypeIdTo = (String) context.get("roleTypeIdTo");
        String partyRelationshipTypeId = (String) context.get("partyRelationshipTypeId");

        // Before creating the partyRelationShip, create the partyRoles if they don't exist
        GenericValue partyToRole = null;
        partyToRole =
            delegator.findOne(
                "PartyRole",
                UtilMisc.toMap("partyId", partyIdTo, "roleTypeId", roleTypeIdTo),
                false);
        if (partyToRole == null) {
          partyToRole =
              delegator.makeValue(
                  "PartyRole", UtilMisc.toMap("partyId", partyIdTo, "roleTypeId", roleTypeIdTo));
          partyToRole.create();
        }

        GenericValue partyFromRole = null;
        partyFromRole =
            delegator.findOne(
                "PartyRole",
                UtilMisc.toMap("partyId", partyIdFrom, "roleTypeId", roleTypeIdFrom),
                false);
        if (partyFromRole == null) {
          partyFromRole =
              delegator.makeValue(
                  "PartyRole",
                  UtilMisc.toMap("partyId", partyIdFrom, "roleTypeId", roleTypeIdFrom));
          partyFromRole.create();
        }

        // Check if there is already a partyRelationship of that type with another party from the
        // side indicated
        String sideChecked = partyIdFrom.equals(partyId) ? "partyIdFrom" : "partyIdTo";
        partyRelationShipList =
            delegator.findByAnd(
                "PartyRelationship",
                UtilMisc.toMap(
                    sideChecked,
                    partyId,
                    "roleTypeIdFrom",
                    roleTypeIdFrom,
                    "roleTypeIdTo",
                    roleTypeIdTo,
                    "partyRelationshipTypeId",
                    partyRelationshipTypeId));
        // We consider the last one (in time) as sole active (we try to maintain a unique
        // relationship and keep changes history)
        partyRelationShipList = EntityUtil.filterByDate(partyRelationShipList);
        GenericValue oldPartyRelationShip = EntityUtil.getFirst(partyRelationShipList);
        if (UtilValidate.isNotEmpty(oldPartyRelationShip)) {
          oldPartyRelationShip.setFields(
              UtilMisc.toMap("thruDate", UtilDateTime.nowTimestamp())); // Current becomes inactive
          oldPartyRelationShip.store();
        }
        try {
          dispatcher.runSync("createPartyRelationship", context); // Create new one
        } catch (GenericServiceException e) {
          Debug.logWarning(e.getMessage(), module);
          return ServiceUtil.returnError(
              "Could not create party relationship (write failure): " + e.getMessage());
        }
      }
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          "Could not create party relationship (write failure): " + e.getMessage());
    }
    result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
    return result;
  }
  private static void handlePartyTaxExempt(
      GenericValue adjValue,
      Set<String> billToPartyIdSet,
      String taxAuthGeoId,
      String taxAuthPartyId,
      BigDecimal taxAmount,
      Timestamp nowTimestamp,
      Delegator delegator)
      throws GenericEntityException {
    Debug.logInfo("Checking for tax exemption : " + taxAuthGeoId + " / " + taxAuthPartyId, module);
    List<EntityCondition> ptiConditionList =
        UtilMisc.<EntityCondition>toList(
            EntityCondition.makeCondition("partyId", EntityOperator.IN, billToPartyIdSet),
            EntityCondition.makeCondition("taxAuthGeoId", EntityOperator.EQUALS, taxAuthGeoId),
            EntityCondition.makeCondition("taxAuthPartyId", EntityOperator.EQUALS, taxAuthPartyId));
    ptiConditionList.add(
        EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp));
    ptiConditionList.add(
        EntityCondition.makeCondition(
            EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null),
            EntityOperator.OR,
            EntityCondition.makeCondition("thruDate", EntityOperator.GREATER_THAN, nowTimestamp)));
    EntityCondition ptiCondition =
        EntityCondition.makeCondition(ptiConditionList, EntityOperator.AND);
    // sort by -fromDate to get the newest (largest) first, just in case there is more than one, we
    // only want the most recent valid one, should only be one per jurisdiction...
    List<GenericValue> partyTaxInfos =
        delegator.findList(
            "PartyTaxAuthInfo", ptiCondition, null, UtilMisc.toList("-fromDate"), null, false);

    boolean foundExemption = false;
    if (partyTaxInfos.size() > 0) {
      GenericValue partyTaxInfo = partyTaxInfos.get(0);
      adjValue.set("customerReferenceId", partyTaxInfo.get("partyTaxId"));
      if ("Y".equals(partyTaxInfo.getString("isExempt"))) {
        adjValue.set("amount", BigDecimal.ZERO);
        adjValue.set("exemptAmount", taxAmount);
        foundExemption = true;
      }
    }

    // if no exceptions were found for the current; try the parent
    if (!foundExemption) {
      // try the "parent" TaxAuthority
      List<GenericValue> taxAuthorityAssocList =
          delegator.findByAndCache(
              "TaxAuthorityAssoc",
              UtilMisc.toMap(
                  "toTaxAuthGeoId",
                  taxAuthGeoId,
                  "toTaxAuthPartyId",
                  taxAuthPartyId,
                  "taxAuthorityAssocTypeId",
                  "EXEMPT_INHER"),
              UtilMisc.toList("-fromDate"));
      taxAuthorityAssocList = EntityUtil.filterByDate(taxAuthorityAssocList, true);
      GenericValue taxAuthorityAssoc = EntityUtil.getFirst(taxAuthorityAssocList);
      // Debug.logInfo("Parent assoc to " + taxAuthGeoId + " : " + taxAuthorityAssoc, module);
      if (taxAuthorityAssoc != null) {
        handlePartyTaxExempt(
            adjValue,
            billToPartyIdSet,
            taxAuthorityAssoc.getString("taxAuthGeoId"),
            taxAuthorityAssoc.getString("taxAuthPartyId"),
            taxAmount,
            nowTimestamp,
            delegator);
      }
    }
  }