/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.shopping.service.impl; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.model.ResourceConstants; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.permission.ModelPermissions; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.spring.extender.service.ServiceReference; import com.liferay.shopping.configuration.ShoppingFileUploadsConfiguration; import com.liferay.shopping.exception.DuplicateItemFieldNameException; import com.liferay.shopping.exception.DuplicateItemSKUException; import com.liferay.shopping.exception.ItemLargeImageNameException; import com.liferay.shopping.exception.ItemLargeImageSizeException; import com.liferay.shopping.exception.ItemMediumImageNameException; import com.liferay.shopping.exception.ItemMediumImageSizeException; import com.liferay.shopping.exception.ItemNameException; import com.liferay.shopping.exception.ItemSKUException; import com.liferay.shopping.exception.ItemSmallImageNameException; import com.liferay.shopping.exception.ItemSmallImageSizeException; import com.liferay.shopping.model.ShoppingCategory; import com.liferay.shopping.model.ShoppingCategoryConstants; import com.liferay.shopping.model.ShoppingItem; import com.liferay.shopping.model.ShoppingItemField; import com.liferay.shopping.model.ShoppingItemPrice; import com.liferay.shopping.model.ShoppingItemPriceConstants; import com.liferay.shopping.service.base.ShoppingItemLocalServiceBaseImpl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Brian Wing Shun Chan */ public class ShoppingItemLocalServiceImpl extends ShoppingItemLocalServiceBaseImpl { @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 { // Item User user = userLocalService.getUser(userId); sku = StringUtil.toUpperCase(StringUtil.trim(sku)); 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, itemFields); 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.isEmpty()); 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.getModelPermissions()); } // 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; } @Override public void addItemResources( long itemId, boolean addGroupPermissions, boolean addGuestPermissions) throws PortalException { ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId); addItemResources(item, addGroupPermissions, addGuestPermissions); } @Override public void addItemResources(long itemId, ModelPermissions modelPermissions) throws PortalException { ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId); addItemResources(item, modelPermissions); } @Override public void addItemResources( ShoppingItem item, boolean addGroupPermissions, boolean addGuestPermissions) throws PortalException { resourceLocalService.addResources( item.getCompanyId(), item.getGroupId(), item.getUserId(), ShoppingItem.class.getName(), item.getItemId(), false, addGroupPermissions, addGuestPermissions); } @Override public void addItemResources( ShoppingItem item, ModelPermissions modelPermissions) throws PortalException { resourceLocalService.addModelResources( item.getCompanyId(), item.getGroupId(), item.getUserId(), ShoppingItem.class.getName(), item.getItemId(), modelPermissions); } @Override public void deleteItem(long itemId) throws PortalException { ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId); deleteItem(item); } @Override public void deleteItem(ShoppingItem item) throws PortalException { // 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()); } @Override public void deleteItems(long groupId, long categoryId) throws PortalException { List<ShoppingItem> items = shoppingItemPersistence.findByG_C( groupId, categoryId); for (ShoppingItem item : items) { deleteItem(item); } } @Override public int getCategoriesItemsCount(long groupId, List<Long> categoryIds) { return shoppingItemFinder.countByG_C(groupId, categoryIds); } @Override public List<ShoppingItem> getFeaturedItems( long groupId, long categoryId, int numOfItems) { List<ShoppingItem> featuredItems = shoppingItemFinder.findByFeatured( groupId, new long[] {categoryId}, numOfItems); if (featuredItems.isEmpty()) { List<ShoppingCategory> childCategories = shoppingCategoryPersistence.findByG_P(groupId, categoryId); if (!childCategories.isEmpty()) { long[] categoryIds = new long[childCategories.size()]; for (int i = 0; i < childCategories.size(); i++) { ShoppingCategory childCategory = childCategories.get(i); categoryIds[i] = childCategory.getCategoryId(); } featuredItems = shoppingItemFinder.findByFeatured( groupId, categoryIds, numOfItems); } } return featuredItems; } @Override public ShoppingItem getItem(long itemId) throws PortalException { return shoppingItemPersistence.findByPrimaryKey(itemId); } @Override public ShoppingItem getItem(long companyId, String sku) throws PortalException { return shoppingItemPersistence.findByC_S(companyId, sku); } @Override public ShoppingItem getItemByLargeImageId(long largeImageId) throws PortalException { return shoppingItemPersistence.findByLargeImageId(largeImageId); } @Override public ShoppingItem getItemByMediumImageId(long mediumImageId) throws PortalException { return shoppingItemPersistence.findByMediumImageId(mediumImageId); } @Override public ShoppingItem getItemBySmallImageId(long smallImageId) throws PortalException { return shoppingItemPersistence.findBySmallImageId(smallImageId); } @Override public List<ShoppingItem> getItems(long groupId, long categoryId) { return shoppingItemPersistence.findByG_C(groupId, categoryId); } @Override public List<ShoppingItem> getItems( long groupId, long categoryId, int start, int end, OrderByComparator<ShoppingItem> obc) { return shoppingItemPersistence.findByG_C( groupId, categoryId, start, end, obc); } @Override public int getItemsCount(long groupId, long categoryId) { return shoppingItemPersistence.countByG_C(groupId, categoryId); } @Override public ShoppingItem[] getItemsPrevAndNext( long itemId, OrderByComparator<ShoppingItem> obc) throws PortalException { ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId); return shoppingItemPersistence.findByG_C_PrevAndNext( item.getItemId(), item.getGroupId(), item.getCategoryId(), obc); } @Override public List<ShoppingItem> getSaleItems( long groupId, long categoryId, int numOfItems) { List<ShoppingItem> saleItems = shoppingItemFinder.findBySale( groupId, new long[] {categoryId}, numOfItems); if (saleItems.isEmpty()) { List<ShoppingCategory> childCategories = shoppingCategoryPersistence.findByG_P(groupId, categoryId); if (!childCategories.isEmpty()) { 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; } @Override public List<ShoppingItem> search( long groupId, long[] categoryIds, String keywords, int start, int end) { return shoppingItemFinder.findByKeywords( groupId, categoryIds, keywords, start, end); } @Override public List<ShoppingItem> search( long groupId, long[] categoryIds, String keywords, int start, int end, OrderByComparator<ShoppingItem> obc) { return shoppingItemFinder.findByKeywords( groupId, categoryIds, keywords, start, end, obc); } @Override public int searchCount(long groupId, long[] categoryIds, String keywords) { return shoppingItemFinder.countByKeywords( groupId, categoryIds, keywords); } @Override public int searchCount( long groupId, long[] categoryIds, String keywords, OrderByComparator<ShoppingItem> obc) { return shoppingItemFinder.countByKeywords( groupId, categoryIds, keywords, obc); } @Override public ShoppingItem updateItem( long userId, long itemId, 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 { // Item ShoppingItem item = shoppingItemPersistence.findByPrimaryKey(itemId); User user = userLocalService.getUser(userId); categoryId = getCategory(item, categoryId); sku = StringUtil.toUpperCase(StringUtil.trim(sku)); 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) { } validate( user.getCompanyId(), itemId, sku, name, smallImage, smallImageURL, smallImageFile, smallImageBytes, mediumImage, mediumImageURL, mediumImageFile, mediumImageBytes, largeImage, largeImageURL, largeImageFile, largeImageBytes, itemFields); item.setModifiedDate(new Date()); item.setCategoryId(categoryId); item.setSku(sku); item.setName(name); item.setDescription(description); item.setProperties(properties); item.setFields(!itemFields.isEmpty()); 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.setSmallImageURL(smallImageURL); item.setMediumImage(mediumImage); item.setMediumImageURL(mediumImageURL); item.setLargeImage(largeImage); item.setLargeImageURL(largeImageURL); shoppingItemPersistence.update(item); // Images saveImages( smallImage, item.getSmallImageId(), smallImageFile, smallImageBytes, mediumImage, item.getMediumImageId(), mediumImageFile, mediumImageBytes, largeImage, item.getLargeImageId(), largeImageFile, largeImageBytes); // Item fields shoppingItemFieldPersistence.removeByItemId(itemId); 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 shoppingItemPricePersistence.removeByItemId(itemId); if (itemPrices.size() > 1) { for (ShoppingItemPrice itemPrice : itemPrices) { long itemPriceId = counterLocalService.increment(); itemPrice.setItemPriceId(itemPriceId); itemPrice.setItemId(itemId); shoppingItemPricePersistence.update(itemPrice); } } return item; } protected String checkItemField(String value) { return StringUtil.removeChars( value, CharPool.AMPERSAND, CharPool.APOSTROPHE, CharPool.EQUAL, CharPool.PIPE, CharPool.QUOTE); } protected long getCategory(ShoppingItem item, long categoryId) { 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; } protected void saveImages( boolean smallImage, long smallImageId, File smallImageFile, byte[] smallImageBytes, boolean mediumImage, long mediumImageId, File mediumImageFile, byte[] mediumImageBytes, boolean largeImage, long largeImageId, File largeImageFile, byte[] largeImageBytes) throws PortalException { // Small image if (smallImage) { if ((smallImageFile != null) && (smallImageBytes != null)) { imageLocalService.updateImage(smallImageId, smallImageBytes); } } else { imageLocalService.deleteImage(smallImageId); } // Medium image if (mediumImage) { if ((mediumImageFile != null) && (mediumImageBytes != null)) { imageLocalService.updateImage(mediumImageId, mediumImageBytes); } } else { imageLocalService.deleteImage(mediumImageId); } // Large image if (largeImage) { if ((largeImageFile != null) && (largeImageBytes != null)) { imageLocalService.updateImage(largeImageId, largeImageBytes); } } else { imageLocalService.deleteImage(largeImageId); } } 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, List<ShoppingItemField> itemFields) throws PortalException { if (Validator.isNull(sku)) { throw new ItemSKUException(); } ShoppingItem item = shoppingItemPersistence.fetchByC_S(companyId, sku); if ((item != null) && (item.getItemId() != itemId)) { StringBundler sb = new StringBundler(5); sb.append("{companyId="); sb.append(companyId); sb.append(", sku="); sb.append(sku); sb.append("}"); throw new DuplicateItemSKUException(sb.toString()); } if (Validator.isNull(name)) { throw new ItemNameException(); } if (!itemFields.isEmpty()) { List<String> itemFieldNames = new ArrayList<>(); List<String> duplicateItemFieldNames = new ArrayList<>(); StringBundler sb = new StringBundler(itemFields.size() * 2); for (ShoppingItemField itemField : itemFields) { if (itemFieldNames.contains(itemField.getName())) { if (!duplicateItemFieldNames.contains( itemField.getName())) { duplicateItemFieldNames.add(itemField.getName()); sb.append(itemField.getName()); sb.append(StringPool.COMMA_AND_SPACE); } } else { itemFieldNames.add(itemField.getName()); } } if (!duplicateItemFieldNames.isEmpty()) { sb.setIndex(sb.index() - 1); throw new DuplicateItemFieldNameException(sb.toString()); } } String[] imageExtensions = _shoppingFileUploadsConfiguration.imageExtensions(); // Small image if (smallImage && Validator.isNull(smallImageURL) && (smallImageFile != null) && (smallImageBytes != null)) { String smallImageName = smallImageFile.getName(); if (smallImageName != null) { boolean validSmallImageExtension = false; for (String imageExtension : imageExtensions) { if (StringPool.STAR.equals(imageExtension) || StringUtil.endsWith(smallImageName, imageExtension)) { validSmallImageExtension = true; break; } } if (!validSmallImageExtension) { throw new ItemSmallImageNameException(smallImageName); } } long smallImageMaxSize = _shoppingFileUploadsConfiguration.smallImageMaxSize(); 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 (String imageExtension : imageExtensions) { if (StringPool.STAR.equals(imageExtension) || StringUtil.endsWith(mediumImageName, imageExtension)) { validMediumImageExtension = true; break; } } if (!validMediumImageExtension) { throw new ItemMediumImageNameException(mediumImageName); } } long mediumImageMaxSize = _shoppingFileUploadsConfiguration.mediumImageMaxSize(); 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 (String imageExtension : imageExtensions) { if (StringPool.STAR.equals(imageExtension) || StringUtil.endsWith(largeImageName, imageExtension)) { validLargeImageExtension = true; break; } } if (!validLargeImageExtension) { throw new ItemLargeImageNameException(largeImageName); } } long largeImageMaxSize = _shoppingFileUploadsConfiguration.largeImageMaxSize(); if ((largeImageMaxSize > 0) && ((largeImageBytes == null) || (largeImageBytes.length > largeImageMaxSize))) { throw new ItemLargeImageSizeException(); } } @ServiceReference(type = ShoppingFileUploadsConfiguration.class) private ShoppingFileUploadsConfiguration _shoppingFileUploadsConfiguration; }