/** Method to get a condition that checks that the given fieldName is in a given timePeriod. */
  public static EntityCondition getFilterByPeriodExpr(String fieldName, GenericValue timePeriod) {
    Timestamp fromDate;
    Timestamp thruDate;
    if (timePeriod.get("fromDate") instanceof Timestamp) {
      fromDate = timePeriod.getTimestamp("fromDate");
      thruDate = timePeriod.getTimestamp("thruDate");
    } else {
      fromDate = UtilDateTime.toTimestamp(timePeriod.getDate("fromDate"));
      thruDate = UtilDateTime.toTimestamp(timePeriod.getDate("thruDate"));
    }

    EntityConditionList betweenCondition =
        EntityCondition.makeCondition(
            EntityCondition.makeCondition(fieldName, EntityOperator.GREATER_THAN, fromDate),
            EntityCondition.makeCondition(fieldName, EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
    return EntityCondition.makeCondition(
        EntityCondition.makeCondition(fieldName, EntityOperator.NOT_EQUAL, null), betweenCondition);
  }
  /**
   * Gets the end time of the recurrence rule or 0 if none.
   *
   * @return long The timestamp of the end time for this rule or 0 for none.
   */
  public long getEndTime() {
    if (rule == null) {
      Debug.logVerbose("Rule is null.", module);
      return -1;
    }
    long time = 0;
    java.sql.Timestamp stamp = null;

    stamp = rule.getTimestamp("untilDateTime");
    Debug.logVerbose("Stamp value: " + stamp, module);

    if (stamp != null) {
      long nanos = stamp.getNanos();
      time = stamp.getTime();
      time += (nanos / 1000000);
    }
    Debug.logVerbose("Returning time: " + time, module);
    return time;
  }
Exemple #3
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;
   }
 }
  /**
   * Makes a list of TrackingCodeOrder entities to be attached to the current order; called by the
   * createOrder event; the values in the returned List will not have the orderId set
   */
  public static List<GenericValue> makeTrackingCodeOrders(HttpServletRequest request) {
    Delegator delegator = (Delegator) request.getAttribute("delegator");
    java.sql.Timestamp nowStamp = UtilDateTime.nowTimestamp();
    List<GenericValue> trackingCodeOrders = FastList.newInstance();

    Cookie[] cookies = request.getCookies();
    Timestamp affiliateReferredTimeStamp = null;
    String siteId = null;
    String isBillable = null;
    String trackingCodeId = null;
    if (cookies != null && cookies.length > 0) {
      for (int i = 0; i < cookies.length; i++) {
        String cookieName = cookies[i].getName();

        Debug.logInfo(" cookieName is " + cookieName, module);
        Debug.logInfo(" cookieValue is " + cookies[i].getValue(), module);
        // find the siteId cookie if it exists
        if ("Ofbiz.TKCD.SiteId".equals(cookieName)) {
          siteId = cookies[i].getValue();
        }

        // find the referred timestamp cookie if it exists
        if ("Ofbiz.TKCD.UpdatedTimeStamp".equals(cookieName)) {
          String affiliateReferredTime = cookies[i].getValue();
          if (affiliateReferredTime != null && !affiliateReferredTime.equals("")) {
            try {
              affiliateReferredTimeStamp = Timestamp.valueOf(affiliateReferredTime);
            } catch (IllegalArgumentException e) {
              Debug.logError(
                  e, "Error parsing affiliateReferredTimeStamp value from cookie", module);
            }
          }
        }

        // find any that start with TKCDB_ for billable tracking code cookies with isBillable=Y
        // also and for each TKCDT_ cookie that doesn't have a corresponding billable code add it to
        // the list with isBillable=N
        // This cookie value keeps trackingCodeId
        if (cookieName.startsWith("TKCDB_")) {
          isBillable = "Y";
          trackingCodeId = cookies[i].getValue();
        } else if (cookieName.startsWith("TKCDT_")) {
          isBillable = "N";
          trackingCodeId = cookies[i].getValue();
        }
      }
    }
    GenericValue trackingCode = null;
    try {
      trackingCode =
          delegator.findByPrimaryKeyCache(
              "TrackingCode", UtilMisc.toMap("trackingCodeId", trackingCodeId));
    } catch (GenericEntityException e) {
      Debug.logError(
          e,
          "Error looking up TrackingCode with trackingCodeId ["
              + trackingCodeId
              + "], ignoring this trackingCodeId",
          module);
    }

    if (trackingCode != null) {
      // check effective dates
      if (trackingCode.get("fromDate") != null
          && nowStamp.before(trackingCode.getTimestamp("fromDate"))) {
        if (Debug.infoOn())
          Debug.logInfo(
              "The TrackingCode with ID ["
                  + trackingCodeId
                  + "] has not yet gone into effect, ignoring this trackingCodeId",
              module);
      }
      if (trackingCode.get("thruDate") != null
          && nowStamp.after(trackingCode.getTimestamp("thruDate"))) {
        if (Debug.infoOn())
          Debug.logInfo(
              "The TrackingCode with ID ["
                  + trackingCodeId
                  + "] has expired, ignoring this trackingCodeId",
              module);
      }
      GenericValue trackingCodeOrder =
          delegator.makeValue(
              "TrackingCodeOrder",
              UtilMisc.toMap(
                  "trackingCodeTypeId",
                  trackingCode.get("trackingCodeTypeId"),
                  "trackingCodeId",
                  trackingCodeId,
                  "isBillable",
                  isBillable,
                  "siteId",
                  siteId,
                  "hasExported",
                  "N",
                  "affiliateReferredTimeStamp",
                  affiliateReferredTimeStamp));

      Debug.logInfo(" trackingCodeOrder is " + trackingCodeOrder, module);
      trackingCodeOrders.add(trackingCodeOrder);
    } else {
      // Only log an error if there was a trackingCodeId to begin with
      if (trackingCodeId != null) {
        Debug.logError(
            "TrackingCode not found for trackingCodeId ["
                + trackingCodeId
                + "], ignoring this trackingCodeId.",
            module);
      }
    }

    return trackingCodeOrders;
  }
  public static String checkAccessTrackingCode(
      HttpServletRequest request, HttpServletResponse response) {
    Delegator delegator = (Delegator) request.getAttribute("delegator");
    java.sql.Timestamp nowStamp = UtilDateTime.nowTimestamp();

    String trackingCodeId = request.getParameter("autoTrackingCode");
    if (UtilValidate.isEmpty(trackingCodeId)) trackingCodeId = request.getParameter("atc");
    if (UtilValidate.isEmpty(trackingCodeId)) {
      Cookie[] cookies = request.getCookies();
      if (cookies != null) {
        for (Cookie cookie : cookies) {
          if ("TKCDT_ACCESS".equals(cookie.getName())) {
            trackingCodeId = cookie.getValue();
          }
        }
      }
    }

    if (UtilValidate.isNotEmpty(trackingCodeId)) {
      // find the tracking code object
      GenericValue trackingCode = null;
      try {
        trackingCode =
            delegator.findByPrimaryKeyCache(
                "TrackingCode", UtilMisc.toMap("trackingCodeId", trackingCodeId));
      } catch (GenericEntityException e) {
        Debug.logError(
            e,
            "Error looking up TrackingCode with trackingCodeId ["
                + trackingCodeId
                + "], ignoring this trackingCodeId",
            module);
      }
      if (trackingCode != null) {
        // verify the tracking code type
        if ("ACCESS".equals(trackingCode.getString("trackingCodeTypeId"))) {
          // verify the effective date
          if (trackingCode.get("fromDate") != null
              && nowStamp.after(trackingCode.getTimestamp("fromDate"))) {
            if (trackingCode.get("thruDate") != null
                && nowStamp.before(trackingCode.getTimestamp("thruDate"))) {
              // tracking code is valid
              return "success";
            } else {
              if (Debug.infoOn())
                Debug.logInfo(
                    "The TrackingCode with ID ["
                        + trackingCodeId
                        + "] has expired, ignoring this trackingCodeId",
                    module);
              request.setAttribute(
                  "_ERROR_MESSAGE_", "Access code [" + trackingCodeId + "], is not valid.");
            }
          } else {
            if (Debug.infoOn())
              Debug.logInfo(
                  "The TrackingCode with ID ["
                      + trackingCodeId
                      + "] has not yet gone into effect, ignoring this trackingCodeId",
                  module);
            request.setAttribute(
                "_ERROR_MESSAGE_", "Access code [" + trackingCodeId + "], is not valid.");
          }
        } else {
          Debug.logWarning(
              "Tracking code found ["
                  + trackingCodeId
                  + "] but was not of the type ACCESS; access denied",
              module);
          request.setAttribute(
              "_ERROR_MESSAGE_", "Access code [" + trackingCodeId + "] not found.");
        }
      } else {
        request.setAttribute("_ERROR_MESSAGE_", "Access code [" + trackingCodeId + "] not found.");
      }
    }

    // no tracking code or tracking code invalid; redirect to the access page (i.e. request named
    // 'protect')
    return ":_protect_:";
  }
  /**
   * If attaching TrackingCode Cookies to the visit is desired this event should be added to the
   * list of events that run on the first hit in a visit.
   */
  public static String checkTrackingCodeCookies(
      HttpServletRequest request, HttpServletResponse response) {
    Delegator delegator = (Delegator) request.getAttribute("delegator");
    java.sql.Timestamp nowStamp = UtilDateTime.nowTimestamp();
    GenericValue visit = VisitHandler.getVisit(request.getSession());
    if (visit == null) {
      Debug.logWarning(
          "Could not get visit, not checking trackingCode cookies to associate with visit", module);
    } else {
      // loop through cookies and look for ones with a name that starts with TKCDT_ for trackable
      // cookies
      Cookie[] cookies = request.getCookies();

      if (cookies != null && cookies.length > 0) {
        for (int i = 0; i < cookies.length; i++) {
          if (cookies[i].getName().startsWith("TKCDT_")) {
            String trackingCodeId = cookies[i].getValue();
            GenericValue trackingCode;
            try {
              trackingCode =
                  delegator.findByPrimaryKeyCache(
                      "TrackingCode", UtilMisc.toMap("trackingCodeId", trackingCodeId));
            } catch (GenericEntityException e) {
              Debug.logError(
                  e,
                  "Error looking up TrackingCode with trackingCodeId ["
                      + trackingCodeId
                      + "], ignoring this trackingCodeId",
                  module);
              continue;
            }

            if (trackingCode == null) {
              Debug.logError(
                  "TrackingCode not found for trackingCodeId ["
                      + trackingCodeId
                      + "], ignoring this trackingCodeId.",
                  module);
              // this return value will be ignored, but we'll designate this as an error anyway
              continue;
            }

            // check effective dates
            if (trackingCode.get("fromDate") != null
                && nowStamp.before(trackingCode.getTimestamp("fromDate"))) {
              if (Debug.infoOn())
                Debug.logInfo(
                    "The TrackingCode with ID ["
                        + trackingCodeId
                        + "] has not yet gone into effect, ignoring this trackingCodeId",
                    module);
              continue;
            }
            if (trackingCode.get("thruDate") != null
                && nowStamp.after(trackingCode.getTimestamp("thruDate"))) {
              if (Debug.infoOn())
                Debug.logInfo(
                    "The TrackingCode with ID ["
                        + trackingCodeId
                        + "] has expired, ignoring this trackingCodeId",
                    module);
              continue;
            }

            // for each trackingCodeId found in this way attach to the visit with the TKCDSRC_COOKIE
            // sourceEnumId
            GenericValue trackingCodeVisit =
                delegator.makeValue(
                    "TrackingCodeVisit",
                    UtilMisc.toMap(
                        "trackingCodeId",
                        trackingCodeId,
                        "visitId",
                        visit.get("visitId"),
                        "fromDate",
                        nowStamp,
                        "sourceEnumId",
                        "TKCDSRC_COOKIE"));
            try {
              // not doing this inside a transaction, want each one possible to go in
              trackingCodeVisit.create();
            } catch (GenericEntityException e) {
              Debug.logError(e, "Error while saving TrackingCodeVisit", module);
              // don't return error, want to get as many as possible: return "error";
            }
          }
        }
      }
    }

    return "success";
  }
  private static String processTrackingCode(
      GenericValue trackingCode, HttpServletRequest request, HttpServletResponse response) {
    Delegator delegator = (Delegator) request.getAttribute("delegator");
    String trackingCodeId = trackingCode.getString("trackingCodeId");

    // check effective dates
    java.sql.Timestamp nowStamp = UtilDateTime.nowTimestamp();
    if (trackingCode.get("fromDate") != null
        && nowStamp.before(trackingCode.getTimestamp("fromDate"))) {
      if (Debug.infoOn())
        Debug.logInfo(
            "The TrackingCode with ID ["
                + trackingCodeId
                + "] has not yet gone into effect, ignoring this trackingCodeId",
            module);
      return "success";
    }
    if (trackingCode.get("thruDate") != null
        && nowStamp.after(trackingCode.getTimestamp("thruDate"))) {
      if (Debug.infoOn())
        Debug.logInfo(
            "The TrackingCode with ID ["
                + trackingCodeId
                + "] has expired, ignoring this trackingCodeId",
            module);
      return "success";
    }

    // persist that info by associating with the current visit
    GenericValue visit = VisitHandler.getVisit(request.getSession());
    if (visit == null) {
      Debug.logWarning(
          "Could not get visit, not associating trackingCode [" + trackingCodeId + "] with visit",
          module);
    } else {
      GenericValue trackingCodeVisit =
          delegator.makeValue(
              "TrackingCodeVisit",
              UtilMisc.toMap(
                  "trackingCodeId",
                  trackingCodeId,
                  "visitId",
                  visit.get("visitId"),
                  "fromDate",
                  UtilDateTime.nowTimestamp(),
                  "sourceEnumId",
                  "TKCDSRC_URL_PARAM"));
      try {
        trackingCodeVisit.create();
      } catch (GenericEntityException e) {
        Debug.logError(e, "Error while saving TrackingCodeVisit", module);
      }
    }

    // write trackingCode cookies with the value set to the trackingCodeId
    // NOTE: just write these cookies and if others exist from other tracking codes they will be
    // overwritten, ie only keep the newest

    // load the properties from the website entity
    String cookieDomain = null;

    String webSiteId = WebSiteWorker.getWebSiteId(request);
    if (webSiteId != null) {
      try {
        GenericValue webSite =
            delegator.findByPrimaryKeyCache("WebSite", UtilMisc.toMap("webSiteId", webSiteId));
        if (webSite != null) {
          cookieDomain = webSite.getString("cookieDomain");
        }
      } catch (GenericEntityException e) {
        Debug.logWarning(
            e, "Problems with WebSite entity; using global default cookie domain", module);
      }
    }

    if (cookieDomain == null) {
      cookieDomain = UtilProperties.getPropertyValue("url", "cookie.domain", "");
    }

    // if trackingCode.trackableLifetime not null and is > 0 write a trackable cookie with name in
    // the form: TKCDT_{trackingCode.trackingCodeTypeId} and timeout will be
    // trackingCode.trackableLifetime
    Long trackableLifetime = trackingCode.getLong("trackableLifetime");
    if (trackableLifetime != null
        && (trackableLifetime.longValue() > 0 || trackableLifetime.longValue() == -1)) {
      Cookie trackableCookie =
          new Cookie(
              "TKCDT_" + trackingCode.getString("trackingCodeTypeId"),
              trackingCode.getString("trackingCodeId"));
      if (trackableLifetime.longValue() > 0)
        trackableCookie.setMaxAge(trackableLifetime.intValue());
      trackableCookie.setPath("/");
      if (cookieDomain.length() > 0) trackableCookie.setDomain(cookieDomain);
      response.addCookie(trackableCookie);
    }

    // if trackingCode.billableLifetime not null and is > 0 write a billable cookie with name in the
    // form: TKCDB_{trackingCode.trackingCodeTypeId} and timeout will be
    // trackingCode.billableLifetime
    Long billableLifetime = trackingCode.getLong("billableLifetime");
    if (billableLifetime != null
        && (billableLifetime.longValue() > 0 || billableLifetime.longValue() == -1)) {
      Cookie billableCookie =
          new Cookie(
              "TKCDB_" + trackingCode.getString("trackingCodeTypeId"),
              trackingCode.getString("trackingCodeId"));
      if (billableLifetime.longValue() > 0) billableCookie.setMaxAge(billableLifetime.intValue());
      billableCookie.setPath("/");
      if (cookieDomain.length() > 0) billableCookie.setDomain(cookieDomain);
      response.addCookie(billableCookie);
    }

    // if site id exist in cookies then it is not required to create it, if exist with different
    // site then create it
    int siteIdCookieAge = (60 * 60 * 24 * 365); // should this be configurable?
    String siteId = request.getParameter("siteId");
    if (UtilValidate.isNotEmpty(siteId)) {
      String visitorSiteIdCookieName = "Ofbiz.TKCD.SiteId";
      String visitorSiteId = null;
      // first try to get the current ID from the visitor cookie
      javax.servlet.http.Cookie[] cookies = request.getCookies();
      if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
          if (cookies[i].getName().equals(visitorSiteIdCookieName)) {
            visitorSiteId = cookies[i].getValue();
            break;
          }
        }
      }

      if (visitorSiteId == null || (visitorSiteId != null && !visitorSiteId.equals(siteId))) {
        // if trackingCode.siteId is  not null  write a trackable cookie with name in the form:
        // Ofbiz.TKCSiteId and timeout will be 60 * 60 * 24 * 365
        Cookie siteIdCookie = new Cookie("Ofbiz.TKCD.SiteId", siteId);
        siteIdCookie.setMaxAge(siteIdCookieAge);
        siteIdCookie.setPath("/");
        if (cookieDomain.length() > 0) siteIdCookie.setDomain(cookieDomain);
        response.addCookie(siteIdCookie);
        // if trackingCode.siteId is  not null  write a trackable cookie with name in the form:
        // Ofbiz.TKCSiteId and timeout will be 60 * 60 * 24 * 365
        Cookie updatedTimeStampCookie =
            new Cookie("Ofbiz.TKCD.UpdatedTimeStamp", UtilDateTime.nowTimestamp().toString());
        updatedTimeStampCookie.setMaxAge(siteIdCookieAge);
        updatedTimeStampCookie.setPath("/");
        if (cookieDomain.length() > 0) updatedTimeStampCookie.setDomain(cookieDomain);
        response.addCookie(updatedTimeStampCookie);
      }
    }

    // if we have overridden logo, css and/or catalogId set some session attributes
    HttpSession session = request.getSession();
    String overrideLogo = trackingCode.getString("overrideLogo");
    if (overrideLogo != null) session.setAttribute("overrideLogo", overrideLogo);
    String overrideCss = trackingCode.getString("overrideCss");
    if (overrideCss != null) session.setAttribute("overrideCss", overrideCss);
    String prodCatalogId = trackingCode.getString("prodCatalogId");
    if (UtilValidate.isNotEmpty(prodCatalogId)) {
      session.setAttribute("CURRENT_CATALOG_ID", prodCatalogId);
      CategoryWorker.setTrail(request, FastList.<String>newInstance());
    }

    // if forward/redirect is needed, do a response.sendRedirect and return null to tell the control
    // servlet to not do any other requests/views
    String redirectUrl = trackingCode.getString("redirectUrl");
    if (UtilValidate.isNotEmpty(redirectUrl)) {
      try {
        response.sendRedirect(redirectUrl);
      } catch (java.io.IOException e) {
        Debug.logError(
            e, "Could not redirect as requested in the trackingCode to: " + redirectUrl, module);
      }
      return null;
    }

    return "success";
  }
  /** Restores the specialized (auto-save) shopping list back into the shopping cart */
  public static String restoreAutoSaveList(
      HttpServletRequest request, HttpServletResponse response) {
    Delegator delegator = (Delegator) request.getAttribute("delegator");
    LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
    GenericValue productStore = ProductStoreWorker.getProductStore(request);

    if (!ProductStoreWorker.autoSaveCart(productStore)) {
      // if auto-save is disabled just return here
      return "success";
    }

    HttpSession session = request.getSession();
    ShoppingCart cart = ShoppingCartEvents.getCartObject(request);

    // safety check for missing required parameter.
    if (cart.getWebSiteId() == null) {
      cart.setWebSiteId(WebSiteWorker.getWebSiteId(request));
    }

    // locate the user's identity
    GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
    if (userLogin == null) {
      userLogin = (GenericValue) session.getAttribute("autoUserLogin");
    }

    // find the list ID
    String autoSaveListId = cart.getAutoSaveListId();
    if (autoSaveListId == null) {
      try {
        autoSaveListId =
            getAutoSaveListId(delegator, dispatcher, null, userLogin, cart.getProductStoreId());
      } catch (GeneralException e) {
        Debug.logError(e, module);
      }
      cart.setAutoSaveListId(autoSaveListId);
    } else if (userLogin != null) {
      String existingAutoSaveListId = null;
      try {
        existingAutoSaveListId =
            getAutoSaveListId(delegator, dispatcher, null, userLogin, cart.getProductStoreId());
      } catch (GeneralException e) {
        Debug.logError(e, module);
      }
      if (existingAutoSaveListId != null) {
        if (!existingAutoSaveListId.equals(autoSaveListId)) {
          // Replace with existing shopping list
          cart.setAutoSaveListId(existingAutoSaveListId);
          autoSaveListId = existingAutoSaveListId;
          cart.setLastListRestore(null);
        } else {
          // CASE: User first login and logout and then re-login again. This condition does not
          // require a restore at all
          // because at this point items in the cart and the items in the shopping list are same so
          // just return.
          return "success";
        }
      }
    }

    // check to see if we are okay to load this list
    java.sql.Timestamp lastLoad = cart.getLastListRestore();
    boolean okayToLoad = autoSaveListId == null ? false : (lastLoad == null ? true : false);
    if (!okayToLoad && lastLoad != null) {
      GenericValue shoppingList = null;
      try {
        shoppingList =
            EntityQuery.use(delegator)
                .from("ShoppingList")
                .where("shoppingListId", autoSaveListId)
                .queryOne();
      } catch (GenericEntityException e) {
        Debug.logError(e, module);
      }
      if (shoppingList != null) {
        java.sql.Timestamp lastModified = shoppingList.getTimestamp("lastAdminModified");
        if (lastModified != null) {
          if (lastModified.after(lastLoad)) {
            okayToLoad = true;
          }
          if (cart.size() == 0 && lastModified.after(cart.getCartCreatedTime())) {
            okayToLoad = true;
          }
        }
      }
    }

    // load (restore) the list of we have determined it is okay to load
    if (okayToLoad) {
      String prodCatalogId = CatalogWorker.getCurrentCatalogId(request);
      try {
        addListToCart(
            delegator,
            dispatcher,
            cart,
            prodCatalogId,
            autoSaveListId,
            false,
            false,
            userLogin != null ? true : false);
        cart.setLastListRestore(UtilDateTime.nowTimestamp());
      } catch (IllegalArgumentException e) {
        Debug.logError(e, module);
      }
    }

    return "success";
  }
  public static String addListToCart(
      Delegator delegator,
      LocalDispatcher dispatcher,
      ShoppingCart cart,
      String prodCatalogId,
      String shoppingListId,
      boolean includeChild,
      boolean setAsListItem,
      boolean append)
      throws java.lang.IllegalArgumentException {
    String errMsg = null;

    // no list; no add
    if (shoppingListId == null) {
      errMsg =
          UtilProperties.getMessage(
              resource_error, "shoppinglistevents.choose_shopping_list", cart.getLocale());
      throw new IllegalArgumentException(errMsg);
    }

    // get the shopping list
    GenericValue shoppingList = null;
    List<GenericValue> shoppingListItems = null;
    try {
      shoppingList =
          EntityQuery.use(delegator)
              .from("ShoppingList")
              .where("shoppingListId", shoppingListId)
              .queryOne();
      if (shoppingList == null) {
        errMsg =
            UtilProperties.getMessage(
                resource_error,
                "shoppinglistevents.error_getting_shopping_list_and_items",
                cart.getLocale());
        throw new IllegalArgumentException(errMsg);
      }

      shoppingListItems = shoppingList.getRelated("ShoppingListItem", null, null, false);
      if (shoppingListItems == null) {
        shoppingListItems = FastList.newInstance();
      }

      // include all items of child lists if flagged to do so
      if (includeChild) {
        List<GenericValue> childShoppingLists =
            shoppingList.getRelated("ChildShoppingList", null, null, false);
        for (GenericValue v : childShoppingLists) {
          List<GenericValue> items = v.getRelated("ShoppingListItem", null, null, false);
          shoppingListItems.addAll(items);
        }
      }

    } catch (GenericEntityException e) {
      Debug.logError(e, "Problems getting ShoppingList and ShoppingListItem records", module);
      errMsg =
          UtilProperties.getMessage(
              resource_error,
              "shoppinglistevents.error_getting_shopping_list_and_items",
              cart.getLocale());
      throw new IllegalArgumentException(errMsg);
    }

    // no items; not an error; just mention that nothing was added
    if (UtilValidate.isEmpty(shoppingListItems)) {
      errMsg =
          UtilProperties.getMessage(
              resource_error, "shoppinglistevents.no_items_added", cart.getLocale());
      return errMsg;
    }

    // check if we are to clear the cart first
    if (!append) {
      cart.clear();
      // Prevent the system from creating a new shopping list every time the cart is restored for
      // anonymous user.
      cart.setAutoSaveListId(shoppingListId);
    }

    // get the survey info for all the items
    Map<String, List<String>> shoppingListSurveyInfo = getItemSurveyInfos(shoppingListItems);

    // add the items
    StringBuilder eventMessage = new StringBuilder();
    for (GenericValue shoppingListItem : shoppingListItems) {
      String productId = shoppingListItem.getString("productId");
      BigDecimal quantity = shoppingListItem.getBigDecimal("quantity");
      Timestamp reservStart = shoppingListItem.getTimestamp("reservStart");
      BigDecimal reservLength = shoppingListItem.getBigDecimal("reservLength");
      BigDecimal reservPersons = shoppingListItem.getBigDecimal("reservPersons");
      //    String accommodationMapId = shoppingListItem.getString("accommodationMapId");
      //    String accommodationSpotId = shoppingListItem.getString("accommodationSpotId");
      String configId = shoppingListItem.getString("configId");
      try {
        String listId = shoppingListItem.getString("shoppingListId");
        String itemId = shoppingListItem.getString("shoppingListItemSeqId");

        Map<String, Object> attributes = FastMap.newInstance();
        // list items are noted in the shopping cart
        if (setAsListItem) {
          attributes.put("shoppingListId", listId);
          attributes.put("shoppingListItemSeqId", itemId);
        }

        // check if we have existing survey responses to append
        if (shoppingListSurveyInfo.containsKey(listId + "." + itemId)
            && UtilValidate.isNotEmpty(shoppingListSurveyInfo.get(listId + "." + itemId))) {
          attributes.put("surveyResponses", shoppingListSurveyInfo.get(listId + "." + itemId));
        }

        ProductConfigWrapper configWrapper = null;
        if (UtilValidate.isNotEmpty(configId)) {
          configWrapper =
              ProductConfigWorker.loadProductConfigWrapper(
                  delegator,
                  dispatcher,
                  configId,
                  productId,
                  cart.getProductStoreId(),
                  prodCatalogId,
                  cart.getWebSiteId(),
                  cart.getCurrency(),
                  cart.getLocale(),
                  cart.getAutoUserLogin());
        }
        // TODO: add code to check for survey response requirement

        // i cannot get the addOrDecrease function to accept a null reservStart field: i get a null
        // pointer exception a null constant works....
        if (reservStart == null) {
          cart.addOrIncreaseItem(
              productId,
              null,
              quantity,
              null,
              null,
              null,
              null,
              null,
              null,
              attributes,
              prodCatalogId,
              configWrapper,
              null,
              null,
              null,
              dispatcher);
        } else {
          cart.addOrIncreaseItem(
              productId,
              null,
              quantity,
              reservStart,
              reservLength,
              reservPersons,
              null,
              null,
              null,
              null,
              null,
              attributes,
              prodCatalogId,
              configWrapper,
              null,
              null,
              null,
              dispatcher);
        }
        Map<String, Object> messageMap = UtilMisc.<String, Object>toMap("productId", productId);
        errMsg =
            UtilProperties.getMessage(
                resource_error,
                "shoppinglistevents.added_product_to_cart",
                messageMap,
                cart.getLocale());
        eventMessage.append(errMsg).append("\n");
      } catch (CartItemModifyException e) {
        Debug.logWarning(
            e,
            UtilProperties.getMessage(
                resource_error, "OrderProblemsAddingItemFromListToCart", cart.getLocale()));
        Map<String, Object> messageMap = UtilMisc.<String, Object>toMap("productId", productId);
        errMsg =
            UtilProperties.getMessage(
                resource_error,
                "shoppinglistevents.problem_adding_product_to_cart",
                messageMap,
                cart.getLocale());
        eventMessage.append(errMsg).append("\n");
      } catch (ItemNotFoundException e) {
        Debug.logWarning(
            e, UtilProperties.getMessage(resource_error, "OrderProductNotFound", cart.getLocale()));
        Map<String, Object> messageMap = UtilMisc.<String, Object>toMap("productId", productId);
        errMsg =
            UtilProperties.getMessage(
                resource_error,
                "shoppinglistevents.problem_adding_product_to_cart",
                messageMap,
                cart.getLocale());
        eventMessage.append(errMsg).append("\n");
      }
    }

    if (eventMessage.length() > 0) {
      return eventMessage.toString();
    }

    // all done
    return ""; // no message to return; will simply reply as success
  }
  // base deposit service
  public static Map<String, Object> finAccountDeposit(
      DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    GenericValue userLogin = (GenericValue) context.get("userLogin");
    String productStoreId = (String) context.get("productStoreId");
    String finAccountId = (String) context.get("finAccountId");
    String orderItemSeqId = (String) context.get("orderItemSeqId");
    String reasonEnumId = (String) context.get("reasonEnumId");
    String orderId = (String) context.get("orderId");
    Boolean isRefund = (Boolean) context.get("isRefund");
    BigDecimal amount = (BigDecimal) context.get("amount");

    final String DEPOSIT = isRefund == null || !isRefund ? "DEPOSIT" : "ADJUSTMENT";

    String partyId = (String) context.get("partyId");
    if (UtilValidate.isEmpty(partyId)) {
      partyId = "_NA_";
    }
    String currencyUom = (String) context.get("currency");
    if (UtilValidate.isEmpty(currencyUom)) {
      currencyUom =
          EntityUtilProperties.getPropertyValue(
              "general.properties", "currency.uom.id.default", "USD", delegator);
    }

    GenericValue finAccount;
    try {
      finAccount =
          EntityQuery.use(delegator)
              .from("FinAccount")
              .where("finAccountId", finAccountId)
              .queryOne();
    } catch (GenericEntityException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountNotFound",
              UtilMisc.toMap("finAccountId", finAccountId),
              locale));
    }

    // verify we have a financial account
    if (finAccount == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountNotFound",
              UtilMisc.toMap("finAccountId", ""),
              locale));
    }

    // make sure the fin account itself has not expired
    if ((finAccount.getTimestamp("thruDate") != null)
        && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountExpired",
              UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")),
              locale));
    }
    Debug.logInfo("Deposit into financial account #" + finAccountId + " [" + amount + "]", module);

    // get the previous balance
    BigDecimal previousBalance = finAccount.getBigDecimal("actualBalance");
    if (previousBalance == null) {
      previousBalance = FinAccountHelper.ZERO;
    }

    // create the transaction
    BigDecimal actualBalance;
    String refNum;
    try {
      refNum =
          FinAccountPaymentServices.createFinAcctPaymentTransaction(
              delegator,
              dispatcher,
              userLogin,
              amount,
              productStoreId,
              partyId,
              orderId,
              orderItemSeqId,
              currencyUom,
              DEPOSIT,
              finAccountId,
              reasonEnumId);
      finAccount.refresh();
      actualBalance = finAccount.getBigDecimal("actualBalance");
    } catch (GeneralException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }

    // make sure balance is not null
    if (actualBalance == null) {
      actualBalance = FinAccountHelper.ZERO;
    } else {
      if (actualBalance.compareTo(BigDecimal.ZERO) < 0) {
        // balance went below zero, set negative pending replenishment status so that no more auths
        // or captures will go through until it is replenished
        try {
          Map<String, Object> rollbackCtx =
              UtilMisc.toMap(
                  "userLogin",
                  userLogin,
                  "finAccountId",
                  finAccountId,
                  "statusId",
                  "FNACT_NEGPENDREPL");
          dispatcher.addRollbackService("updateFinAccount", rollbackCtx, true);
        } catch (GenericServiceException e) {
          Debug.logError(e, module);
          return ServiceUtil.returnError(e.getMessage());
        }
      }
    }

    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("previousBalance", previousBalance);
    result.put("balance", actualBalance);
    result.put("amount", amount);
    result.put("processResult", Boolean.TRUE);
    result.put("referenceNum", refNum);
    return result;
  }
  // base account transaction services
  public static Map<String, Object> finAccountWithdraw(
      DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    GenericValue userLogin = (GenericValue) context.get("userLogin");
    String productStoreId = (String) context.get("productStoreId");
    String finAccountId = (String) context.get("finAccountId");
    String orderItemSeqId = (String) context.get("orderItemSeqId");
    String reasonEnumId = (String) context.get("reasonEnumId");
    String orderId = (String) context.get("orderId");
    Boolean requireBalance = (Boolean) context.get("requireBalance");
    BigDecimal amount = (BigDecimal) context.get("amount");
    if (requireBalance == null) requireBalance = Boolean.TRUE;

    final String WITHDRAWAL = "WITHDRAWAL";

    String partyId = (String) context.get("partyId");
    if (UtilValidate.isEmpty(partyId)) {
      partyId = "_NA_";
    }
    String currencyUom = (String) context.get("currency");
    if (UtilValidate.isEmpty(currencyUom)) {
      currencyUom =
          EntityUtilProperties.getPropertyValue(
              "general.properties", "currency.uom.id.default", "USD", delegator);
    }

    // validate the amount
    if (amount.compareTo(BigDecimal.ZERO) < 0) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resourceError, "AccountingFinAccountMustBePositive", locale));
    }

    GenericValue finAccount;
    try {
      finAccount =
          EntityQuery.use(delegator)
              .from("FinAccount")
              .where("finAccountId", finAccountId)
              .queryOne();
    } catch (GenericEntityException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }

    // verify we have a financial account
    if (finAccount == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountNotFound",
              UtilMisc.toMap("finAccountId", ""),
              locale));
    }

    // make sure the fin account itself has not expired
    if ((finAccount.getTimestamp("thruDate") != null)
        && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountExpired",
              UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")),
              locale));
    }

    // check the actual balance (excluding authorized amounts) and create the transaction if it is
    // sufficient
    BigDecimal previousBalance = finAccount.getBigDecimal("actualBalance");
    if (previousBalance == null) {
      previousBalance = FinAccountHelper.ZERO;
    }

    BigDecimal balance;
    String refNum;
    Boolean procResult;
    if (requireBalance && previousBalance.compareTo(amount) < 0) {
      procResult = Boolean.FALSE;
      balance = previousBalance;
      refNum = "N/A";
    } else {
      try {
        refNum =
            FinAccountPaymentServices.createFinAcctPaymentTransaction(
                delegator,
                dispatcher,
                userLogin,
                amount,
                productStoreId,
                partyId,
                orderId,
                orderItemSeqId,
                currencyUom,
                WITHDRAWAL,
                finAccountId,
                reasonEnumId);
        finAccount.refresh();
        balance = finAccount.getBigDecimal("actualBalance");
        procResult = Boolean.TRUE;
      } catch (GeneralException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
      }
    }

    // make sure balance is not null
    if (balance == null) {
      balance = FinAccountHelper.ZERO;
    }

    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("previousBalance", previousBalance);
    result.put("balance", balance);
    result.put("amount", amount);
    result.put("processResult", procResult);
    result.put("referenceNum", refNum);
    return result;
  }
  // base payment integration services
  public static Map<String, Object> finAccountPreAuth(
      DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    Locale locale = (Locale) context.get("locale");
    GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
    String finAccountCode = (String) context.get("finAccountCode");
    String finAccountPin = (String) context.get("finAccountPin");
    String finAccountId = (String) context.get("finAccountId");
    String orderId = (String) context.get("orderId");
    BigDecimal amount = (BigDecimal) context.get("processAmount");

    // check for an existing auth trans and cancel it
    GenericValue authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
    if (authTrans != null) {
      Map<String, Object> input =
          UtilMisc.toMap("userLogin", userLogin, "finAccountAuthId", authTrans.get("referenceNum"));
      try {
        dispatcher.runSync("expireFinAccountAuth", input);
      } catch (GenericServiceException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
      }
    }
    if (finAccountId == null && paymentPref != null) {
      finAccountId = paymentPref.getString("finAccountId");
    }

    // obtain the order information
    OrderReadHelper orh = new OrderReadHelper(delegator, orderId);

    // NOTE DEJ20070808: this means that we want store related settings for where the item is being
    // purchased,
    // NOT where the account was setup; should this be changed to use settings from the store where
    // the account was setup?
    String productStoreId = orh.getProductStoreId();

    // TODO, NOTE DEJ20070808: why is this setup this way anyway? for the allowAuthToNegative
    // wouldn't that be better setup
    // on the FinAccount and not on the ProductStoreFinActSetting? maybe an override on the
    // FinAccount would be good...

    // get the financial account
    GenericValue finAccount;
    if (finAccountId != null) {
      try {
        finAccount =
            EntityQuery.use(delegator)
                .from("FinAccount")
                .where("finAccountId", finAccountId)
                .queryOne();
      } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
      }
    } else {
      if (finAccountCode != null) {
        try {
          finAccount = FinAccountHelper.getFinAccountFromCode(finAccountCode, delegator);
        } catch (GenericEntityException e) {
          Debug.logError(e, module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resourceError, "AccountingFinAccountCannotLocateItFromAccountCode", locale));
        }
      } else {
        return ServiceUtil.returnError(
            UtilProperties.getMessage(
                resourceError, "AccountingFinAccountIdAndFinAccountCodeAreNull", locale));
      }
    }
    if (finAccount == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resourceError, "AccountingFinAccountIdInvalid", locale));
    }

    String finAccountTypeId = finAccount.getString("finAccountTypeId");
    finAccountId = finAccount.getString("finAccountId");
    String statusId = finAccount.getString("statusId");

    try {
      // fin the store requires a pin number; validate the PIN with the code
      Map<String, Object> findProductStoreFinActSettingMap =
          UtilMisc.<String, Object>toMap(
              "productStoreId", productStoreId, "finAccountTypeId", finAccountTypeId);
      GenericValue finAccountSettings =
          EntityQuery.use(delegator)
              .from("ProductStoreFinActSetting")
              .where(findProductStoreFinActSettingMap)
              .cache()
              .queryOne();

      if (finAccountSettings == null) {
        Debug.logWarning(
            "In finAccountPreAuth could not find ProductStoreFinActSetting record, values searched by: "
                + findProductStoreFinActSettingMap,
            module);
      }
      if (Debug.verboseOn())
        Debug.logVerbose("In finAccountPreAuth finAccountSettings=" + finAccountSettings, module);

      BigDecimal minBalance = FinAccountHelper.ZERO;
      String allowAuthToNegative = "N";

      if (finAccountSettings != null) {
        allowAuthToNegative = finAccountSettings.getString("allowAuthToNegative");
        minBalance = finAccountSettings.getBigDecimal("minBalance");
        if (minBalance == null) {
          minBalance = FinAccountHelper.ZERO;
        }

        // validate the PIN if the store requires it
        if ("Y".equals(finAccountSettings.getString("requirePinCode"))) {
          if (!FinAccountHelper.validatePin(delegator, finAccountCode, finAccountPin)) {
            Map<String, Object> result = ServiceUtil.returnSuccess();
            result.put(
                "authMessage",
                UtilProperties.getMessage(
                    resourceError, "AccountingFinAccountPinCodeCombinatorNotFound", locale));
            result.put("authResult", Boolean.FALSE);
            result.put("processAmount", amount);
            result.put("authFlag", "0");
            result.put("authCode", "A");
            result.put("authRefNum", "0");
            Debug.logWarning("Unable to auth FinAccount: " + result, module);
            return result;
          }
        }
      }

      // check for expiration date
      if ((finAccount.getTimestamp("thruDate") != null)
          && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
        Map<String, Object> result = ServiceUtil.returnSuccess();
        result.put(
            "authMessage",
            UtilProperties.getMessage(
                resourceError,
                "AccountingFinAccountExpired",
                UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")),
                locale));
        result.put("authResult", Boolean.FALSE);
        result.put("processAmount", amount);
        result.put("authFlag", "0");
        result.put("authCode", "A");
        result.put("authRefNum", "0");
        Debug.logWarning("Unable to auth FinAccount: " + result, module);
        return result;
      }

      // check for account being in bad standing somehow
      if ("FNACT_NEGPENDREPL".equals(statusId)
          || "FNACT_MANFROZEN".equals(statusId)
          || "FNACT_CANCELLED".equals(statusId)) {
        // refresh the finaccount
        finAccount.refresh();
        statusId = finAccount.getString("statusId");

        if ("FNACT_NEGPENDREPL".equals(statusId)
            || "FNACT_MANFROZEN".equals(statusId)
            || "FNACT_CANCELLED".equals(statusId)) {
          Map<String, Object> result = ServiceUtil.returnSuccess();
          if ("FNACT_NEGPENDREPL".equals(statusId)) {
            result.put(
                "authMessage",
                UtilProperties.getMessage(resourceError, "AccountingFinAccountNegative", locale));
          } else if ("FNACT_MANFROZEN".equals(statusId)) {
            result.put(
                "authMessage",
                UtilProperties.getMessage(resourceError, "AccountingFinAccountFrozen", locale));
          } else if ("FNACT_CANCELLED".equals(statusId)) {
            result.put(
                "authMessage",
                UtilProperties.getMessage(resourceError, "AccountingFinAccountCancelled", locale));
          }
          result.put("authResult", Boolean.FALSE);
          result.put("processAmount", amount);
          result.put("authFlag", "0");
          result.put("authCode", "A");
          result.put("authRefNum", "0");
          Debug.logWarning("Unable to auth FinAccount: " + result, module);
          return result;
        }
      }

      // check the amount to authorize against the available balance of fin account, which includes
      // active authorizations as well as transactions
      BigDecimal availableBalance = finAccount.getBigDecimal("availableBalance");
      if (availableBalance == null) {
        availableBalance = FinAccountHelper.ZERO;
      } else {
        BigDecimal availableBalanceOriginal = availableBalance;
        availableBalance =
            availableBalance.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
        if (availableBalance.compareTo(availableBalanceOriginal) != 0) {
          Debug.logWarning(
              "In finAccountPreAuth for finAccountId ["
                  + finAccountId
                  + "] availableBalance ["
                  + availableBalanceOriginal
                  + "] was different after rounding ["
                  + availableBalance
                  + "]; it should never have made it into the database this way, so check whatever put it there.",
              module);
        }
      }

      Map<String, Object> result = ServiceUtil.returnSuccess();
      String authMessage = null;
      Boolean processResult;
      String refNum;

      // make sure to round and scale it to the same as availableBalance
      amount = amount.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);

      Debug.logInfo(
          "Allow auth to negative: "
              + allowAuthToNegative
              + " :: available: "
              + availableBalance
              + " comp: "
              + minBalance
              + " = "
              + availableBalance.compareTo(minBalance)
              + " :: req: "
              + amount,
          module);
      // check the available balance to see if we can auth this tx
      if (("Y".equals(allowAuthToNegative) && availableBalance.compareTo(minBalance) > -1)
          || (availableBalance.compareTo(amount) > -1)) {
        Timestamp thruDate;

        if (finAccountSettings != null && finAccountSettings.getLong("authValidDays") != null) {
          thruDate =
              UtilDateTime.getDayEnd(
                  UtilDateTime.nowTimestamp(), finAccountSettings.getLong("authValidDays"));
        } else {
          thruDate =
              UtilDateTime.getDayEnd(
                  UtilDateTime.nowTimestamp(), Long.valueOf(30)); // default 30 days for an auth
        }

        Map<String, Object> tmpResult =
            dispatcher.runSync(
                "createFinAccountAuth",
                UtilMisc.<String, Object>toMap(
                    "finAccountId",
                    finAccountId,
                    "amount",
                    amount,
                    "thruDate",
                    thruDate,
                    "userLogin",
                    userLogin));

        if (ServiceUtil.isError(tmpResult)) {
          return tmpResult;
        }
        refNum = (String) tmpResult.get("finAccountAuthId");
        processResult = Boolean.TRUE;

        // refresh the account
        finAccount.refresh();
      } else {
        Debug.logWarning(
            "Attempted to authorize ["
                + amount
                + "] against a balance of only ["
                + availableBalance
                + "] for finAccountId ["
                + finAccountId
                + "]",
            module);
        refNum = "0"; // a refNum is always required from authorization
        authMessage = "Insufficient funds";
        processResult = Boolean.FALSE;
      }

      result.put("processAmount", amount);
      result.put("authMessage", authMessage);
      result.put("authResult", processResult);
      result.put("processAmount", amount);
      result.put("authFlag", "1");
      result.put("authCode", "A");
      result.put("authRefNum", refNum);
      Debug.logInfo("FinAccont Auth: " + result, module);

      return result;
    } catch (GenericEntityException ex) {
      Debug.logError(ex, "Cannot authorize financial account", module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountCannotBeAuthorized",
              UtilMisc.toMap("errorString", ex.getMessage()),
              locale));
    } catch (GenericServiceException ex) {
      Debug.logError(ex, "Cannot authorize financial account", module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountCannotBeAuthorized",
              UtilMisc.toMap("errorString", ex.getMessage()),
              locale));
    }
  }
  public static Map<String, Object> finAccountCapture(
      DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    GenericValue authTrans = (GenericValue) context.get("authTrans");
    BigDecimal amount = (BigDecimal) context.get("captureAmount");
    String currency = (String) context.get("currency");

    // get the authorization transaction
    if (authTrans == null) {
      authTrans = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference);
    }
    if (authTrans == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotCapture", locale));
    }

    // get the auth record
    String finAccountAuthId = authTrans.getString("referenceNum");
    GenericValue finAccountAuth;
    try {
      finAccountAuth =
          EntityQuery.use(delegator)
              .from("FinAccountAuth")
              .where("finAccountAuthId", finAccountAuthId)
              .queryOne();
    } catch (GenericEntityException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }
    Debug.logInfo(
        "Financial account capture ["
            + finAccountAuth.get("finAccountId")
            + "] for the amount of $"
            + amount
            + " Tx #"
            + finAccountAuth.get("finAccountAuthId"),
        module);

    // get the financial account
    GenericValue finAccount;
    try {
      finAccount = finAccountAuth.getRelatedOne("FinAccount", false);
    } catch (GenericEntityException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }

    // make sure authorization has not expired
    Timestamp authExpiration = finAccountAuth.getTimestamp("thruDate");
    if ((authExpiration != null) && (authExpiration.before(UtilDateTime.nowTimestamp()))) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountAuthorizationExpired",
              UtilMisc.toMap(
                  "paymentGatewayResponseId",
                  authTrans.getString("paymentGatewayResponseId"),
                  "authExpiration",
                  authExpiration),
              locale));
    }

    // make sure the fin account itself has not expired
    if ((finAccount.getTimestamp("thruDate") != null)
        && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resourceError,
              "AccountingFinAccountExpired",
              UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")),
              locale));
    }
    String finAccountId = finAccount.getString("finAccountId");

    // need the product store ID & party ID
    String orderId = orderPaymentPreference.getString("orderId");
    String productStoreId = null;
    String partyId = null;
    if (orderId != null) {
      OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
      productStoreId = orh.getProductStoreId();

      GenericValue billToParty = orh.getBillToParty();
      if (billToParty != null) {
        partyId = billToParty.getString("partyId");
      }
    }

    // BIG NOTE: make sure the expireFinAccountAuth and finAccountWithdraw services are done in the
    // SAME TRANSACTION
    // (i.e. no require-new-transaction in either of them AND no running async)

    // cancel the authorization before doing the withdraw to avoid problems with way negative
    // available amount on account; should happen in same transaction to avoid conflict problems
    Map<String, Object> releaseResult;
    try {
      releaseResult =
          dispatcher.runSync(
              "expireFinAccountAuth",
              UtilMisc.<String, Object>toMap(
                  "userLogin", userLogin, "finAccountAuthId", finAccountAuthId));
    } catch (GenericServiceException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }
    if (ServiceUtil.isError(releaseResult)) {
      return releaseResult;
    }

    // build the withdraw context
    Map<String, Object> withdrawCtx = new HashMap<String, Object>();
    withdrawCtx.put("finAccountId", finAccountId);
    withdrawCtx.put("productStoreId", productStoreId);
    withdrawCtx.put("currency", currency);
    withdrawCtx.put("partyId", partyId);
    withdrawCtx.put("orderId", orderId);
    withdrawCtx.put("amount", amount);
    withdrawCtx.put("reasonEnumId", "FATR_PURCHASE");
    withdrawCtx.put("requireBalance", Boolean.FALSE); // for captures; if auth passed, allow
    withdrawCtx.put("userLogin", userLogin);

    // call the withdraw service
    Map<String, Object> withdrawResp;
    try {
      withdrawResp = dispatcher.runSync("finAccountWithdraw", withdrawCtx);
    } catch (GenericServiceException e) {
      Debug.logError(e, module);
      return ServiceUtil.returnError(e.getMessage());
    }
    if (ServiceUtil.isError(withdrawResp)) {
      return withdrawResp;
    }

    // create the capture response
    Map<String, Object> result = ServiceUtil.returnSuccess();
    Boolean processResult = (Boolean) withdrawResp.get("processResult");
    BigDecimal withdrawAmount = (BigDecimal) withdrawResp.get("amount");
    String referenceNum = (String) withdrawResp.get("referenceNum");
    result.put("captureResult", processResult);
    result.put("captureRefNum", referenceNum);
    result.put("captureCode", "C");
    result.put("captureFlag", "1");
    result.put("captureAmount", withdrawAmount);

    return result;
  }
Exemple #14
0
  public static String timeSheetChecker(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    HttpSession session = request.getSession();
    Delegator delegator = (Delegator) session.getAttribute("delegator");
    GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
    List<Map<String, Object>> noTimeEntryList = new LinkedList<Map<String, Object>>();
    String partyId = userLogin.getString("partyId");
    Timestamp now = UtilDateTime.nowTimestamp();
    Timestamp weekStart = UtilDateTime.getWeekStart(now);

    if (UtilValidate.isEmpty(delegator)) {
      delegator = (Delegator) request.getAttribute("delegator");
    }

    try {
      // should be scrum team or scrum master.
      EntityConditionList<EntityExpr> exprOrs =
          EntityCondition.makeCondition(
              UtilMisc.toList(
                  EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SCRUM_TEAM"),
                  EntityCondition.makeCondition(
                      "roleTypeId", EntityOperator.EQUALS, "SCRUM_MASTER")),
              EntityOperator.OR);
      EntityConditionList<EntityCondition> exprAnds =
          EntityCondition.makeCondition(
              UtilMisc.toList(
                  exprOrs,
                  EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId)),
              EntityOperator.AND);
      List<GenericValue> partyRoleList =
          EntityQuery.use(delegator).from("PartyRole").where(exprAnds).queryList();
      if (UtilValidate.isNotEmpty(partyRoleList)) {
        List<GenericValue> timesheetList =
            EntityQuery.use(delegator)
                .from("Timesheet")
                .where("partyId", partyId, "statusId", "TIMESHEET_IN_PROCESS")
                .cache(true)
                .queryList();
        if (UtilValidate.isNotEmpty(timesheetList)) {
          for (GenericValue timesheetMap : timesheetList) {
            String timesheetId = timesheetMap.getString("timesheetId");
            Timestamp timesheetDate = timesheetMap.getTimestamp("fromDate");
            // check monday - friday
            for (int i = 0; i < 5; i++) {
              Timestamp realTimeDate = UtilDateTime.addDaysToTimestamp(timesheetDate, i);
              Timestamp nowStartDate = UtilDateTime.getDayStart(now);
              // compare week and compare date
              if ((timesheetDate.compareTo(weekStart) <= 0)
                  && (realTimeDate.compareTo(nowStartDate) < 0)) {
                // check time entry
                List<GenericValue> timeEntryList =
                    timesheetMap.getRelated(
                        "TimeEntry",
                        UtilMisc.toMap(
                            "partyId",
                            partyId,
                            "timesheetId",
                            timesheetId,
                            "fromDate",
                            realTimeDate),
                        null,
                        false);
                // check EmplLeave
                List<GenericValue> emplLeaveList =
                    EntityQuery.use(delegator)
                        .from("EmplLeave")
                        .where("partyId", partyId, "fromDate", realTimeDate)
                        .cache(true)
                        .queryList();
                if (UtilValidate.isEmpty(timeEntryList) && UtilValidate.isEmpty(emplLeaveList)) {
                  Map<String, Object> noEntryMap = new HashMap<String, Object>();
                  noEntryMap.put("timesheetId", timesheetId);
                  noTimeEntryList.add(noEntryMap);
                  break;
                }
              }
            }
          }
        }
      }
    } catch (GenericEntityException EntEx) {
      EntEx.printStackTrace();
      Debug.logError(EntEx.getMessage(), module);
    }
    if (UtilValidate.isNotEmpty(noTimeEntryList)) {
      StringBuilder warningDataBuffer = new StringBuilder();
      int size = noTimeEntryList.size();
      for (Map<String, Object> dataMap : noTimeEntryList) {
        if (--size == 0) {
          warningDataBuffer.append(dataMap.get("timesheetId"));
        } else {
          warningDataBuffer.append(dataMap.get("timesheetId")).append(", ");
        }
        warningDataBuffer.append(dataMap.get("timesheetId"));
      }
      String warningData = warningDataBuffer.toString();
      Debug.logInfo("The following time sheet no time entry: [" + warningData + "]", module);
      request.setAttribute(
          "_ERROR_MESSAGE_",
          UtilProperties.getMessage(
              "scrumUiLabels",
              "ScrumTimesheetWarningMessage",
              UtilMisc.toMap("warningMessage", warningData),
              UtilHttp.getLocale(request)));
    }
    return "success";
  }
Exemple #15
0
  public static void indexKeywords(GenericValue product, boolean doAll)
      throws GenericEntityException {
    if (product == null) return;
    Timestamp nowTimestamp = UtilDateTime.nowTimestamp();

    if (!doAll) {
      if ("N".equals(product.getString("autoCreateKeywords"))) {
        return;
      }
      if ("Y".equals(product.getString("isVariant"))
          && "true"
              .equals(UtilProperties.getPropertyValue("prodsearch", "index.ignore.variants"))) {
        return;
      }
      Timestamp salesDiscontinuationDate = product.getTimestamp("salesDiscontinuationDate");
      if (salesDiscontinuationDate != null
          && salesDiscontinuationDate.before(nowTimestamp)
          && "true"
              .equals(
                  UtilProperties.getPropertyValue(
                      "prodsearch", "index.ignore.discontinued.sales"))) {
        return;
      }
    }

    Delegator delegator = product.getDelegator();
    if (delegator == null) return;
    String productId = product.getString("productId");

    // get these in advance just once since they will be used many times for the multiple strings to
    // index
    String separators = KeywordSearchUtil.getSeparators();
    String stopWordBagOr = KeywordSearchUtil.getStopWordBagOr();
    String stopWordBagAnd = KeywordSearchUtil.getStopWordBagAnd();
    boolean removeStems = KeywordSearchUtil.getRemoveStems();
    Set<String> stemSet = KeywordSearchUtil.getStemSet();

    Map<String, Long> keywords = new TreeMap<String, Long>();
    List<String> strings = FastList.newInstance();

    int pidWeight = 1;
    try {
      pidWeight =
          Integer.parseInt(
              UtilProperties.getPropertyValue("prodsearch", "index.weight.Product.productId", "0"));
    } catch (Exception e) {
      Debug.logWarning("Could not parse weight number: " + e.toString(), module);
    }
    keywords.put(product.getString("productId").toLowerCase(), Long.valueOf(pidWeight));

    // Product fields - default is 0 if not found in the properties file
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue(
                "prodsearch", "index.weight.Product.productName", "0"))) {
      addWeightedKeywordSourceString(product, "productName", strings);
    }
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue(
                "prodsearch", "index.weight.Product.internalName", "0"))) {
      addWeightedKeywordSourceString(product, "internalName", strings);
    }
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue("prodsearch", "index.weight.Product.brandName", "0"))) {
      addWeightedKeywordSourceString(product, "brandName", strings);
    }
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue(
                "prodsearch", "index.weight.Product.description", "0"))) {
      addWeightedKeywordSourceString(product, "description", strings);
    }
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue(
                "prodsearch", "index.weight.Product.longDescription", "0"))) {
      addWeightedKeywordSourceString(product, "longDescription", strings);
    }

    // ProductFeatureAppl
    if (!"0"
            .equals(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductFeatureAndAppl.description", "0"))
        || !"0"
            .equals(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductFeatureAndAppl.abbrev", "0"))
        || !"0"
            .equals(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductFeatureAndAppl.idCode", "0"))) {
      // get strings from attributes and features
      List<GenericValue> productFeatureAndAppls =
          delegator.findByAnd("ProductFeatureAndAppl", UtilMisc.toMap("productId", productId));
      for (GenericValue productFeatureAndAppl : productFeatureAndAppls) {
        addWeightedKeywordSourceString(productFeatureAndAppl, "description", strings);
        addWeightedKeywordSourceString(productFeatureAndAppl, "abbrev", strings);
        addWeightedKeywordSourceString(productFeatureAndAppl, "idCode", strings);
      }
    }

    // ProductAttribute
    if (!"0"
            .equals(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductAttribute.attrName", "0"))
        || !"0"
            .equals(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductAttribute.attrValue", "0"))) {
      List<GenericValue> productAttributes =
          delegator.findByAnd("ProductAttribute", UtilMisc.toMap("productId", productId));
      for (GenericValue productAttribute : productAttributes) {
        addWeightedKeywordSourceString(productAttribute, "attrName", strings);
        addWeightedKeywordSourceString(productAttribute, "attrValue", strings);
      }
    }

    // GoodIdentification
    if (!"0"
        .equals(
            UtilProperties.getPropertyValue(
                "prodsearch", "index.weight.GoodIdentification.idValue", "0"))) {
      List<GenericValue> goodIdentifications =
          delegator.findByAnd("GoodIdentification", UtilMisc.toMap("productId", productId));
      for (GenericValue goodIdentification : goodIdentifications) {
        addWeightedKeywordSourceString(goodIdentification, "idValue", strings);
      }
    }

    // Variant Product IDs
    if ("Y".equals(product.getString("isVirtual"))) {
      if (!"0"
          .equals(
              UtilProperties.getPropertyValue(
                  "prodsearch", "index.weight.Variant.Product.productId", "0"))) {
        List<GenericValue> variantProductAssocs =
            delegator.findByAnd(
                "ProductAssoc",
                UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT"));
        variantProductAssocs = EntityUtil.filterByDate(variantProductAssocs);
        for (GenericValue variantProductAssoc : variantProductAssocs) {
          int weight = 1;
          try {
            weight =
                Integer.parseInt(
                    UtilProperties.getPropertyValue(
                        "prodsearch", "index.weight.Variant.Product.productId", "0"));
          } catch (Exception e) {
            Debug.logWarning("Could not parse weight number: " + e.toString(), module);
          }
          for (int i = 0; i < weight; i++) {
            strings.add(variantProductAssoc.getString("productIdTo"));
          }
        }
      }
    }

    String productContentTypes =
        UtilProperties.getPropertyValue("prodsearch", "index.include.ProductContentTypes");
    for (String productContentTypeId : productContentTypes.split(",")) {
      int weight = 1;
      try {
        // this is defaulting to a weight of 1 because you specified you wanted to index this type
        weight =
            Integer.parseInt(
                UtilProperties.getPropertyValue(
                    "prodsearch", "index.weight.ProductContent." + productContentTypeId, "1"));
      } catch (Exception e) {
        Debug.logWarning("Could not parse weight number: " + e.toString(), module);
      }

      List<GenericValue> productContentAndInfos =
          delegator.findByAnd(
              "ProductContentAndInfo",
              UtilMisc.toMap("productId", productId, "productContentTypeId", productContentTypeId),
              null);
      for (GenericValue productContentAndInfo : productContentAndInfos) {
        addWeightedDataResourceString(productContentAndInfo, weight, strings, delegator, product);

        List<GenericValue> alternateViews =
            productContentAndInfo.getRelated(
                "ContentAssocDataResourceViewTo",
                UtilMisc.toMap("caContentAssocTypeId", "ALTERNATE_LOCALE"),
                UtilMisc.toList("-caFromDate"));
        alternateViews =
            EntityUtil.filterByDate(
                alternateViews, UtilDateTime.nowTimestamp(), "caFromDate", "caThruDate", true);
        for (GenericValue thisView : alternateViews) {
          addWeightedDataResourceString(thisView, weight, strings, delegator, product);
        }
      }
    }
    if (UtilValidate.isNotEmpty(strings)) {
      for (String str : strings) {
        // call process keywords method here
        KeywordSearchUtil.processKeywordsForIndex(
            str, keywords, separators, stopWordBagAnd, stopWordBagOr, removeStems, stemSet);
      }
    }

    List<GenericValue> toBeStored = FastList.newInstance();
    int keywordMaxLength =
        Integer.parseInt(
            UtilProperties.getPropertyValue("prodsearch", "product.keyword.max.length"));
    for (Map.Entry<String, Long> entry : keywords.entrySet()) {
      if (entry.getKey().length() <= keywordMaxLength) {
        GenericValue productKeyword =
            delegator.makeValue(
                "ProductKeyword",
                UtilMisc.toMap(
                    "productId",
                    product.getString("productId"),
                    "keyword",
                    entry.getKey(),
                    "keywordTypeId",
                    "KWT_KEYWORD",
                    "relevancyWeight",
                    entry.getValue()));
        toBeStored.add(productKeyword);
      }
    }
    if (toBeStored.size() > 0) {
      if (Debug.verboseOn())
        Debug.logVerbose(
            "[KeywordIndex.indexKeywords] Storing "
                + toBeStored.size()
                + " keywords for productId "
                + product.getString("productId"),
            module);

      if ("true"
          .equals(
              UtilProperties.getPropertyValue("prodsearch", "index.delete.on_index", "false"))) {
        // delete all keywords if the properties file says to
        delegator.removeByAnd(
            "ProductKeyword", UtilMisc.toMap("productId", product.getString("productId")));
      }

      delegator.storeAll(toBeStored);
    }
  }