public static boolean contains(
      PermissionChecker permissionChecker, ShoppingCategory category, String actionId)
      throws PortalException {

    if (actionId.equals(ActionKeys.ADD_CATEGORY)) {
      actionId = ActionKeys.ADD_SUBCATEGORY;
    }

    if (actionId.equals(ActionKeys.VIEW) && PropsValues.PERMISSIONS_VIEW_DYNAMIC_INHERITANCE) {

      long categoryId = category.getCategoryId();

      while (categoryId != ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

        category = ShoppingCategoryLocalServiceUtil.getCategory(categoryId);

        if (!_hasPermission(permissionChecker, category, actionId)) {
          return false;
        }

        categoryId = category.getParentCategoryId();
      }

      return ShoppingPermission.contains(permissionChecker, category.getGroupId(), actionId);
    }

    return _hasPermission(permissionChecker, category, actionId);
  }
  @Override
  public List<ShoppingCategory> getParentCategories(ShoppingCategory category)
      throws PortalException, SystemException {

    List<ShoppingCategory> parentCategories = new ArrayList<ShoppingCategory>();

    ShoppingCategory tempCategory = category;

    while (true) {
      parentCategories.add(tempCategory);

      if (tempCategory.getParentCategoryId()
          == ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

        break;
      }

      tempCategory =
          shoppingCategoryPersistence.findByPrimaryKey(tempCategory.getParentCategoryId());
    }

    Collections.reverse(parentCategories);

    return parentCategories;
  }
  @Override
  public List<ShoppingItem> getSaleItems(long groupId, long categoryId, int numOfItems)
      throws SystemException {

    List<ShoppingItem> saleItems =
        shoppingItemFinder.findBySale(groupId, new long[] {categoryId}, numOfItems);

    if (saleItems.size() == 0) {
      List<ShoppingCategory> childCategories =
          shoppingCategoryPersistence.findByG_P(groupId, categoryId);

      if (childCategories.size() > 0) {
        long[] categoryIds = new long[childCategories.size()];

        for (int i = 0; i < childCategories.size(); i++) {
          ShoppingCategory childCategory = childCategories.get(i);

          categoryIds[i] = childCategory.getCategoryId();
        }

        saleItems = shoppingItemFinder.findBySale(groupId, categoryIds, numOfItems);
      }
    }

    return saleItems;
  }
  protected void mergeCategories(ShoppingCategory fromCategory, long toCategoryId)
      throws PortalException, SystemException {

    List<ShoppingCategory> categories =
        shoppingCategoryPersistence.findByG_P(
            fromCategory.getGroupId(), fromCategory.getCategoryId());

    for (ShoppingCategory category : categories) {
      mergeCategories(category, toCategoryId);
    }

    List<ShoppingItem> items =
        shoppingItemPersistence.findByG_C(fromCategory.getGroupId(), fromCategory.getCategoryId());

    for (ShoppingItem item : items) {

      // Item

      item.setCategoryId(toCategoryId);

      shoppingItemPersistence.update(item);
    }

    deleteCategory(fromCategory);
  }
  protected long getParentCategoryId(ShoppingCategory category, long parentCategoryId)
      throws SystemException {

    if (parentCategoryId == ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

      return parentCategoryId;
    }

    if (category.getCategoryId() == parentCategoryId) {
      return category.getParentCategoryId();
    } else {
      ShoppingCategory parentCategory =
          shoppingCategoryPersistence.fetchByPrimaryKey(parentCategoryId);

      if ((parentCategory == null) || (category.getGroupId() != parentCategory.getGroupId())) {

        return category.getParentCategoryId();
      }

      List<Long> subcategoryIds = new ArrayList<Long>();

      getSubcategoryIds(subcategoryIds, category.getGroupId(), category.getCategoryId());

      if (subcategoryIds.contains(parentCategoryId)) {
        return category.getParentCategoryId();
      }

      return parentCategoryId;
    }
  }
  @Override
  public void getSubcategoryIds(List<Long> categoryIds, long groupId, long categoryId)
      throws SystemException {

    List<ShoppingCategory> categories = shoppingCategoryPersistence.findByG_P(groupId, categoryId);

    for (ShoppingCategory category : categories) {
      categoryIds.add(category.getCategoryId());

      getSubcategoryIds(categoryIds, category.getGroupId(), category.getCategoryId());
    }
  }
  @Override
  public void addCategoryResources(
      ShoppingCategory category, String[] groupPermissions, String[] guestPermissions)
      throws PortalException, SystemException {

    resourceLocalService.addModelResources(
        category.getCompanyId(),
        category.getGroupId(),
        category.getUserId(),
        ShoppingCategory.class.getName(),
        category.getCategoryId(),
        groupPermissions,
        guestPermissions);
  }
  protected long getParentCategoryId(long groupId, long parentCategoryId) throws SystemException {

    if (parentCategoryId != ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

      ShoppingCategory parentCategory =
          shoppingCategoryPersistence.fetchByPrimaryKey(parentCategoryId);

      if ((parentCategory == null) || (groupId != parentCategory.getGroupId())) {

        parentCategoryId = ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
      }
    }

    return parentCategoryId;
  }
  @Override
  public void addCategoryResources(
      ShoppingCategory category, boolean addGroupPermissions, boolean addGuestPermissions)
      throws PortalException, SystemException {

    resourceLocalService.addResources(
        category.getCompanyId(),
        category.getGroupId(),
        category.getUserId(),
        ShoppingCategory.class.getName(),
        category.getCategoryId(),
        false,
        addGroupPermissions,
        addGuestPermissions);
  }
  protected long getCategory(ShoppingItem item, long categoryId) throws SystemException {

    if ((item.getCategoryId() != categoryId)
        && (categoryId != ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID)) {

      ShoppingCategory newCategory = shoppingCategoryPersistence.fetchByPrimaryKey(categoryId);

      if ((newCategory == null) || (item.getGroupId() != newCategory.getGroupId())) {

        categoryId = item.getCategoryId();
      }
    }

    return categoryId;
  }
  public static JSONObject toJSONObject(ShoppingCategory model) {
    JSONObject jsonObj = new JSONObject();

    JSONUtil.put(jsonObj, "categoryId", model.getCategoryId());
    JSONUtil.put(jsonObj, "groupId", model.getGroupId());
    JSONUtil.put(jsonObj, "companyId", model.getCompanyId());
    JSONUtil.put(jsonObj, "userId", model.getUserId());
    JSONUtil.put(jsonObj, "userName", model.getUserName());
    JSONUtil.put(jsonObj, "createDate", model.getCreateDate());
    JSONUtil.put(jsonObj, "modifiedDate", model.getModifiedDate());
    JSONUtil.put(jsonObj, "parentCategoryId", model.getParentCategoryId());
    JSONUtil.put(jsonObj, "name", model.getName());
    JSONUtil.put(jsonObj, "description", model.getDescription());

    return jsonObj;
  }
  @Override
  public ShoppingCategory addCategory(
      long userId,
      long parentCategoryId,
      String name,
      String description,
      ServiceContext serviceContext)
      throws PortalException, SystemException {

    // Category

    User user = userPersistence.findByPrimaryKey(userId);
    long groupId = serviceContext.getScopeGroupId();
    parentCategoryId = getParentCategoryId(groupId, parentCategoryId);
    Date now = new Date();

    validate(name);

    long categoryId = counterLocalService.increment();

    ShoppingCategory category = shoppingCategoryPersistence.create(categoryId);

    category.setGroupId(groupId);
    category.setCompanyId(user.getCompanyId());
    category.setUserId(user.getUserId());
    category.setUserName(user.getFullName());
    category.setCreateDate(now);
    category.setModifiedDate(now);
    category.setParentCategoryId(parentCategoryId);
    category.setName(name);
    category.setDescription(description);

    shoppingCategoryPersistence.update(category);

    // Resources

    if (serviceContext.isAddGroupPermissions() || serviceContext.isAddGuestPermissions()) {

      addCategoryResources(
          category, serviceContext.isAddGroupPermissions(), serviceContext.isAddGuestPermissions());
    } else {
      addCategoryResources(
          category, serviceContext.getGroupPermissions(), serviceContext.getGuestPermissions());
    }

    return category;
  }
  @Override
  public ShoppingCategory getParentCategory(ShoppingCategory category)
      throws PortalException, SystemException {

    ShoppingCategory parentCategory =
        shoppingCategoryPersistence.findByPrimaryKey(category.getParentCategoryId());

    return parentCategory;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }

    if (!(obj instanceof ShoppingCategory)) {
      return false;
    }

    ShoppingCategory shoppingCategory = (ShoppingCategory) obj;

    long primaryKey = shoppingCategory.getPrimaryKey();

    if (getPrimaryKey() == primaryKey) {
      return true;
    } else {
      return false;
    }
  }
  private static boolean _hasPermission(
      PermissionChecker permissionChecker, ShoppingCategory category, String actionId) {

    if (permissionChecker.hasOwnerPermission(
            category.getCompanyId(),
            ShoppingCategory.class.getName(),
            category.getCategoryId(),
            category.getUserId(),
            actionId)
        || permissionChecker.hasPermission(
            category.getGroupId(),
            ShoppingCategory.class.getName(),
            category.getCategoryId(),
            actionId)) {

      return true;
    }

    return false;
  }
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }

    ShoppingCategory shoppingCategory = null;

    try {
      shoppingCategory = (ShoppingCategory) obj;
    } catch (ClassCastException cce) {
      return false;
    }

    long pk = shoppingCategory.getPrimaryKey();

    if (getPrimaryKey() == pk) {
      return true;
    } else {
      return false;
    }
  }
  @Override
  public void deleteCategory(ShoppingCategory category) throws PortalException, SystemException {

    // Categories

    List<ShoppingCategory> categories =
        shoppingCategoryPersistence.findByG_P(category.getGroupId(), category.getCategoryId());

    for (ShoppingCategory curCategory : categories) {
      deleteCategory(curCategory);
    }

    // Category

    shoppingCategoryPersistence.remove(category);

    // Resources

    resourceLocalService.deleteResource(
        category.getCompanyId(),
        ShoppingCategory.class.getName(),
        ResourceConstants.SCOPE_INDIVIDUAL,
        category.getCategoryId());

    // Items

    shoppingItemLocalService.deleteItems(category.getGroupId(), category.getCategoryId());
  }
  @Override
  public ShoppingCategory updateCategory(
      long categoryId,
      long parentCategoryId,
      String name,
      String description,
      boolean mergeWithParentCategory,
      ServiceContext serviceContext)
      throws PortalException, SystemException {

    // Merge categories

    ShoppingCategory category = shoppingCategoryPersistence.findByPrimaryKey(categoryId);

    parentCategoryId = getParentCategoryId(category, parentCategoryId);

    if (mergeWithParentCategory
        && (categoryId != parentCategoryId)
        && (parentCategoryId != ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID)) {

      mergeCategories(category, parentCategoryId);

      return category;
    }

    // Category

    validate(name);

    category.setModifiedDate(new Date());
    category.setParentCategoryId(parentCategoryId);
    category.setName(name);
    category.setDescription(description);

    shoppingCategoryPersistence.update(category);

    return category;
  }
  public int compareTo(ShoppingCategory shoppingCategory) {
    int value = 0;

    if (getParentCategoryId() < shoppingCategory.getParentCategoryId()) {
      value = -1;
    } else if (getParentCategoryId() > shoppingCategory.getParentCategoryId()) {
      value = 1;
    } else {
      value = 0;
    }

    if (value != 0) {
      return value;
    }

    value = getName().toLowerCase().compareTo(shoppingCategory.getName().toLowerCase());

    if (value != 0) {
      return value;
    }

    return 0;
  }
  /**
   * Converts the soap model instance into a normal model instance.
   *
   * @param soapModel the soap model instance to convert
   * @return the normal model instance
   */
  public static ShoppingCategory toModel(ShoppingCategorySoap soapModel) {
    ShoppingCategory model = new ShoppingCategoryImpl();

    model.setCategoryId(soapModel.getCategoryId());
    model.setGroupId(soapModel.getGroupId());
    model.setCompanyId(soapModel.getCompanyId());
    model.setUserId(soapModel.getUserId());
    model.setUserName(soapModel.getUserName());
    model.setCreateDate(soapModel.getCreateDate());
    model.setModifiedDate(soapModel.getModifiedDate());
    model.setParentCategoryId(soapModel.getParentCategoryId());
    model.setName(soapModel.getName());
    model.setDescription(soapModel.getDescription());

    return model;
  }