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);
  }
  public int compare(Object obj1, Object obj2) {
    ShoppingItem item1 = (ShoppingItem) obj1;
    ShoppingItem item2 = (ShoppingItem) obj2;

    Long categoryId1 = new Long(item1.getCategoryId());
    Long categoryId2 = new Long(item2.getCategoryId());

    int value = categoryId1.compareTo(categoryId2);

    if (value == 0) {
      if (item1.getMinQuantity() < item2.getMinQuantity()) {
        value = -1;
      } else if (item1.getMinQuantity() > item2.getMinQuantity()) {
        value = 1;
      }
    }

    if (value == 0) {
      value = item1.getName().toLowerCase().compareTo(item2.getName().toLowerCase());
    }

    if (_ascending) {
      return value;
    } else {
      return -value;
    }
  }
  public ShoppingItem[] getItemsPrevAndNext(long itemId, OrderByComparator obc)
      throws PortalException, SystemException {

    ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId);

    return shoppingItemPersistence.findByG_C_PrevAndNext(
        item.getItemId(), item.getGroupId(), item.getCategoryId(), obc);
  }
  public void addItemResources(
      ShoppingItem item, String[] groupPermissions, String[] guestPermissions)
      throws PortalException, SystemException {

    resourceLocalService.addModelResources(
        item.getCompanyId(),
        item.getGroupId(),
        item.getUserId(),
        ShoppingItem.class.getName(),
        item.getItemId(),
        groupPermissions,
        guestPermissions);
  }
  public void addItemResources(
      ShoppingItem item, boolean addGroupPermissions, boolean addGuestPermissions)
      throws PortalException, SystemException {

    resourceLocalService.addResources(
        item.getCompanyId(),
        item.getGroupId(),
        item.getUserId(),
        ShoppingItem.class.getName(),
        item.getItemId(),
        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 boolean contains(
      PermissionChecker permissionChecker, ShoppingItem item, String actionId)
      throws PortalException, SystemException {

    if (PropsValues.PERMISSIONS_VIEW_DYNAMIC_INHERITANCE) {
      if (item.getCategoryId() != ShoppingCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

        ShoppingCategory category = item.getCategory();

        if (!ShoppingCategoryPermission.contains(permissionChecker, category, ActionKeys.VIEW)) {

          return false;
        }
      }
    }

    if (permissionChecker.hasOwnerPermission(
        item.getCompanyId(),
        ShoppingItem.class.getName(),
        item.getItemId(),
        item.getUserId(),
        actionId)) {

      return true;
    }

    return permissionChecker.hasPermission(
        item.getGroupId(), ShoppingItem.class.getName(), item.getItemId(), actionId);
  }
  @Override
  public void deleteItem(ShoppingItem item) throws PortalException, SystemException {

    // Item

    shoppingItemPersistence.remove(item);

    // Resources

    resourceLocalService.deleteResource(
        item.getCompanyId(),
        ShoppingItem.class.getName(),
        ResourceConstants.SCOPE_INDIVIDUAL,
        item.getItemId());

    // Images

    imageLocalService.deleteImage(item.getSmallImageId());
    imageLocalService.deleteImage(item.getMediumImageId());
    imageLocalService.deleteImage(item.getLargeImageId());

    // Item fields

    shoppingItemFieldPersistence.removeByItemId(item.getItemId());

    // Item prices

    shoppingItemPricePersistence.removeByItemId(item.getItemId());
  }
  protected void validate(
      long companyId,
      long itemId,
      String sku,
      String name,
      boolean smallImage,
      String smallImageURL,
      File smallImageFile,
      byte[] smallImageBytes,
      boolean mediumImage,
      String mediumImageURL,
      File mediumImageFile,
      byte[] mediumImageBytes,
      boolean largeImage,
      String largeImageURL,
      File largeImageFile,
      byte[] largeImageBytes)
      throws PortalException, SystemException {

    if (Validator.isNull(sku)) {
      throw new ItemSKUException();
    }

    ShoppingItem item = shoppingItemPersistence.fetchByC_S(companyId, sku);

    if (item != null) {
      if (itemId > 0) {
        if (item.getItemId() != itemId) {
          throw new DuplicateItemSKUException();
        }
      } else {
        throw new DuplicateItemSKUException();
      }
    }

    if (Validator.isNull(name)) {
      throw new ItemNameException();
    }

    String[] imageExtensions =
        PrefsPropsUtil.getStringArray(PropsKeys.SHOPPING_IMAGE_EXTENSIONS, StringPool.COMMA);

    // Small image

    if (smallImage
        && Validator.isNull(smallImageURL)
        && (smallImageFile != null)
        && (smallImageBytes != null)) {

      String smallImageName = smallImageFile.getName();

      if (smallImageName != null) {
        boolean validSmallImageExtension = false;

        for (int i = 0; i < imageExtensions.length; i++) {
          if (StringPool.STAR.equals(imageExtensions[i])
              || StringUtil.endsWith(smallImageName, imageExtensions[i])) {

            validSmallImageExtension = true;

            break;
          }
        }

        if (!validSmallImageExtension) {
          throw new ItemSmallImageNameException(smallImageName);
        }
      }

      long smallImageMaxSize = PrefsPropsUtil.getLong(PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE);

      if ((smallImageMaxSize > 0)
          && ((smallImageBytes == null) || (smallImageBytes.length > smallImageMaxSize))) {

        throw new ItemSmallImageSizeException();
      }
    }

    // Medium image

    if (mediumImage
        && Validator.isNull(mediumImageURL)
        && (mediumImageFile != null)
        && (mediumImageBytes != null)) {

      String mediumImageName = mediumImageFile.getName();

      if (mediumImageName != null) {
        boolean validMediumImageExtension = false;

        for (int i = 0; i < imageExtensions.length; i++) {
          if (StringPool.STAR.equals(imageExtensions[i])
              || StringUtil.endsWith(mediumImageName, imageExtensions[i])) {

            validMediumImageExtension = true;

            break;
          }
        }

        if (!validMediumImageExtension) {
          throw new ItemMediumImageNameException(mediumImageName);
        }
      }

      long mediumImageMaxSize = PrefsPropsUtil.getLong(PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE);

      if ((mediumImageMaxSize > 0)
          && ((mediumImageBytes == null) || (mediumImageBytes.length > mediumImageMaxSize))) {

        throw new ItemMediumImageSizeException();
      }
    }

    // Large image

    if (!largeImage
        || Validator.isNotNull(largeImageURL)
        || (largeImageFile == null)
        || (largeImageBytes == null)) {

      return;
    }

    String largeImageName = largeImageFile.getName();

    if (largeImageName != null) {
      boolean validLargeImageExtension = false;

      for (int i = 0; i < imageExtensions.length; i++) {
        if (StringPool.STAR.equals(imageExtensions[i])
            || StringUtil.endsWith(largeImageName, imageExtensions[i])) {

          validLargeImageExtension = true;

          break;
        }
      }

      if (!validLargeImageExtension) {
        throw new ItemLargeImageNameException(largeImageName);
      }
    }

    long largeImageMaxSize = PrefsPropsUtil.getLong(PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE);

    if ((largeImageMaxSize > 0)
        && ((largeImageBytes == null) || (largeImageBytes.length > largeImageMaxSize))) {

      throw new ItemLargeImageSizeException();
    }
  }
  @Override
  public ShoppingItem addItem(
      long userId,
      long groupId,
      long categoryId,
      String sku,
      String name,
      String description,
      String properties,
      String fieldsQuantities,
      boolean requiresShipping,
      int stockQuantity,
      boolean featured,
      Boolean sale,
      boolean smallImage,
      String smallImageURL,
      File smallImageFile,
      boolean mediumImage,
      String mediumImageURL,
      File mediumImageFile,
      boolean largeImage,
      String largeImageURL,
      File largeImageFile,
      List<ShoppingItemField> itemFields,
      List<ShoppingItemPrice> itemPrices,
      ServiceContext serviceContext)
      throws PortalException, SystemException {

    // Item

    User user = userPersistence.findByPrimaryKey(userId);
    sku = StringUtil.toUpperCase(sku.trim());

    byte[] smallImageBytes = null;
    byte[] mediumImageBytes = null;
    byte[] largeImageBytes = null;

    try {
      smallImageBytes = FileUtil.getBytes(smallImageFile);
      mediumImageBytes = FileUtil.getBytes(mediumImageFile);
      largeImageBytes = FileUtil.getBytes(largeImageFile);
    } catch (IOException ioe) {
    }

    Date now = new Date();

    validate(
        user.getCompanyId(),
        0,
        sku,
        name,
        smallImage,
        smallImageURL,
        smallImageFile,
        smallImageBytes,
        mediumImage,
        mediumImageURL,
        mediumImageFile,
        mediumImageBytes,
        largeImage,
        largeImageURL,
        largeImageFile,
        largeImageBytes);

    long itemId = counterLocalService.increment();

    ShoppingItem item = shoppingItemPersistence.create(itemId);

    item.setGroupId(groupId);
    item.setCompanyId(user.getCompanyId());
    item.setUserId(user.getUserId());
    item.setUserName(user.getFullName());
    item.setCreateDate(now);
    item.setModifiedDate(now);
    item.setCategoryId(categoryId);
    item.setSku(sku);
    item.setName(name);
    item.setDescription(description);
    item.setProperties(properties);
    item.setFields(itemFields.size() > 0);
    item.setFieldsQuantities(fieldsQuantities);

    for (ShoppingItemPrice itemPrice : itemPrices) {
      if (itemPrice.getStatus() == ShoppingItemPriceConstants.STATUS_ACTIVE_DEFAULT) {

        item.setMinQuantity(itemPrice.getMinQuantity());
        item.setMaxQuantity(itemPrice.getMaxQuantity());
        item.setPrice(itemPrice.getPrice());
        item.setDiscount(itemPrice.getDiscount());
        item.setTaxable(itemPrice.getTaxable());
        item.setShipping(itemPrice.getShipping());
        item.setUseShippingFormula(itemPrice.getUseShippingFormula());
      }

      if ((sale == null)
          && (itemPrice.getDiscount() > 0)
          && ((itemPrice.getStatus() == ShoppingItemPriceConstants.STATUS_ACTIVE_DEFAULT)
              || (itemPrice.getStatus() == ShoppingItemPriceConstants.STATUS_ACTIVE))) {

        sale = Boolean.TRUE;
      }
    }

    item.setRequiresShipping(requiresShipping);
    item.setStockQuantity(stockQuantity);
    item.setFeatured(featured);
    item.setSale((sale != null) ? sale.booleanValue() : false);
    item.setSmallImage(smallImage);
    item.setSmallImageId(counterLocalService.increment());
    item.setSmallImageURL(smallImageURL);
    item.setMediumImage(mediumImage);
    item.setMediumImageId(counterLocalService.increment());
    item.setMediumImageURL(mediumImageURL);
    item.setLargeImage(largeImage);
    item.setLargeImageId(counterLocalService.increment());
    item.setLargeImageURL(largeImageURL);

    shoppingItemPersistence.update(item);

    // Resources

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

      addItemResources(
          item, serviceContext.isAddGroupPermissions(), serviceContext.isAddGuestPermissions());
    } else {
      addItemResources(
          item, serviceContext.getGroupPermissions(), serviceContext.getGuestPermissions());
    }

    // Images

    saveImages(
        smallImage,
        item.getSmallImageId(),
        smallImageFile,
        smallImageBytes,
        mediumImage,
        item.getMediumImageId(),
        mediumImageFile,
        mediumImageBytes,
        largeImage,
        item.getLargeImageId(),
        largeImageFile,
        largeImageBytes);

    // Item fields

    for (ShoppingItemField itemField : itemFields) {
      long itemFieldId = counterLocalService.increment();

      itemField.setItemFieldId(itemFieldId);
      itemField.setItemId(itemId);
      itemField.setName(checkItemField(itemField.getName()));
      itemField.setValues(checkItemField(itemField.getValues()));

      shoppingItemFieldPersistence.update(itemField);
    }

    // Item prices

    if (itemPrices.size() > 1) {
      for (ShoppingItemPrice itemPrice : itemPrices) {
        long itemPriceId = counterLocalService.increment();

        itemPrice.setItemPriceId(itemPriceId);
        itemPrice.setItemId(itemId);

        shoppingItemPricePersistence.update(itemPrice);
      }
    }

    return item;
  }