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);
  }
  @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;
  }