/**
* Most of the code in the Qalingo project is copyrighted Hoteia and licensed
* under the Apache License Version 2.0 (release version 0.8.0)
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Copyright (c) Hoteia, 2012-2014
* http://www.hoteia.com - http://twitter.com/hoteia - contact@hoteia.com
*/
package org.hoteia.qalingo.core.service;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
import org.hoteia.qalingo.core.dao.CartDao;
import org.hoteia.qalingo.core.dao.ProductDao;
import org.hoteia.qalingo.core.domain.Cart;
import org.hoteia.qalingo.core.domain.CartItem;
import org.hoteia.qalingo.core.domain.CartItemTax;
import org.hoteia.qalingo.core.domain.CatalogCategoryVirtual;
import org.hoteia.qalingo.core.domain.Customer;
import org.hoteia.qalingo.core.domain.MarketArea;
import org.hoteia.qalingo.core.domain.ProductMarketing;
import org.hoteia.qalingo.core.domain.ProductMarketingType;
import org.hoteia.qalingo.core.domain.ProductSku;
import org.hoteia.qalingo.core.domain.ProductSkuStorePrice;
import org.hoteia.qalingo.core.domain.Store;
import org.hoteia.qalingo.core.domain.Tax;
import org.hoteia.qalingo.core.fetchplan.catalog.FetchPlanGraphProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("cartService")
@Transactional
public class CartService {
@Autowired
protected CartDao cartDao;
@Autowired
protected ProductDao productDao;
@Autowired
protected CatalogCategoryService catalogCategoryService;
@Autowired
protected ProductService productService;
@Autowired
protected DeliveryMethodService deliveryMethodService;
@Autowired
protected RetailerService retailerService;
@Autowired
protected TaxService taxService;
public void addProductSkuToCart(Cart cart, final String virtualCatalogCode, final String catalogCategoryCode, final String productSkuCode, final int quantity) throws Exception {
addProductSkuToCart(cart, null, virtualCatalogCode, catalogCategoryCode, productSkuCode, quantity);
}
public Cart addProductSkuToCart(Cart cart, Store store, final String virtualCatalogCode, final String catalogCategoryCode, final String productSkuCode, final int quantity) throws Exception {
int finalQuantity = quantity;
if (cart != null) {
Set<CartItem> cartItems = cart.getCartItems();
for (CartItem cartItem : cartItems) {
if (cartItem.getProductSku().getCode().equalsIgnoreCase(productSkuCode) && cartItem.getStoreId().equals(store.getId())) {
finalQuantity = finalQuantity + cartItem.getQuantity();
}
}
}
updateCartItem(cart, store, virtualCatalogCode, catalogCategoryCode, productSkuCode, finalQuantity);
return cart;
}
public Cart updateCartItem(Cart cart, final String productSkuCode, final int quantity) throws Exception {
return updateCartItem(cart, null, null, null, productSkuCode, quantity);
}
public Cart updateCartItem(Cart cart, Store store, final String virtualCatalogCode, final String catalogCategoryCode, final String productSkuCode, final int quantity) throws Exception {
Set<CartItem> cartItems = cart.getCartItems();
boolean productSkuIsNew = true;
for (CartItem cartItem : cartItems) {
if (cartItem.getProductSku().getCode().equalsIgnoreCase(productSkuCode) && Long.compare(store.getId(), cartItem.getStoreId()) == 0) {
cartItem.setQuantity(quantity);
productSkuIsNew = false;
}
}
if (productSkuIsNew) {
final ProductSku productSku = productService.getProductSkuByCode(productSkuCode);
if (productSku != null) {
CartItem cartItem = new CartItem();
cartItem.setProductSku(productSku);
final ProductMarketing reloadedProductMarketing = productService.getProductMarketingByCode(productSku.getProductMarketing().getCode(), FetchPlanGraphProduct.productMarketingDefaultFetchPlan());
cartItem.setProductMarketing(reloadedProductMarketing);
cartItem.setQuantity(quantity);
if (store != null) {
cartItem.setStoreId(store.getId());
}
if (StringUtils.isNotEmpty(catalogCategoryCode)) {
final CatalogCategoryVirtual defaultVirtualCatalogCategory = catalogCategoryService.getVirtualCatalogCategoryByCode(catalogCategoryCode, virtualCatalogCode);
cartItem.setCatalogCategory(defaultVirtualCatalogCategory);
} else {
final List<CatalogCategoryVirtual> catalogCategories = catalogCategoryService.findVirtualCategoriesByProductSkuId(productSku.getId());
final CatalogCategoryVirtual defaultVirtualCatalogCategory = productService.getDefaultVirtualCatalogCategory(reloadedProductMarketing, catalogCategories, true);
cartItem.setCatalogCategory(defaultVirtualCatalogCategory);
}
// TAXES
// List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(store.getId(), productSku.getId());
ProductMarketingType productMarketingType = reloadedProductMarketing.getProductMarketingType();
List<Tax> taxes = taxService.findTaxesByMarketAreaIdAndProductType(cart.getMarketAreaId(), productMarketingType.getCode());
List<CartItemTax> cartItemTaxes = new ArrayList<CartItemTax>();
for (Tax tax : taxes) {
CartItemTax cartItemTax = new CartItemTax();
cartItemTax.setTax(tax);
cartItemTaxes.add(cartItemTax);
}
cartItem.setTaxes(cartItemTaxes);
cart.getCartItems().add(cartItem);
} else {
// TODO : throw ??
}
}
saveOrUpdateCart(cart);
return cart;
}
public Cart deleteCartItem(Cart cart, Store store, final String productSkuCode) throws Exception {
if (cart != null && store != null && productSkuCode != null) {
Set<CartItem> cartItems = new HashSet<CartItem>(cart.getCartItems());
for (CartItem cartItem : cart.getCartItems()) {
if (cartItem.getProductSku().getCode().equalsIgnoreCase(productSkuCode) && cartItem.getStoreId().equals(store.getId())) {
cartItems.remove(cartItem);
}
}
cart.setCartItems(cartItems);
saveOrUpdateCart(cart);
}
return cart;
}
public Cart setShippingAddress(Cart cart, Customer customer, Long customerAddressId) throws Exception {
if (customer.getAddress(customerAddressId) != null) {
cart.setShippingAddressId(customerAddressId);
}
saveOrUpdateCart(cart);
return cart;
}
public Cart setBillingAddress(Cart cart, Customer customer, Long customerAddressId) throws Exception {
if (customer.getAddress(customerAddressId) != null) {
cart.setShippingAddressId(customerAddressId);
}
saveOrUpdateCart(cart);
return cart;
}
public Cart setDeliveryMethod(Cart cart, String deliveryMethodCode) throws Exception {
if (!cart.getDeliveryMethods().isEmpty()) {
cart.getDeliveryMethods().clear();
}
cart.getDeliveryMethods().add(deliveryMethodService.getDeliveryMethodByCode(deliveryMethodCode));
// NO SAVE : Cart DeliveryMethods is @Transient
return cart;
}
public Cart addDeliveryMethod(Cart cart, String deliveryMethodCode) throws Exception {
cart.getDeliveryMethods().add(deliveryMethodService.getDeliveryMethodByCode(deliveryMethodCode));
saveOrUpdateCart(cart);
return cart;
}
public Cart newCustomerCart(final MarketArea marketArea, Customer customer) {
Cart cart = new Cart();
cart.setMarketAreaId(marketArea.getId());
cart.setCustomerId(customer.getId());
saveOrUpdateCart(cart);
return cart;
}
public Cart newGuestCart(final MarketArea marketArea) {
Cart cart = new Cart();
cart.setMarketAreaId(marketArea.getId());
saveOrUpdateCart(cart);
return cart;
}
public Cart getCartById(final Long cartId, Object... params) {
return cartDao.getCartById(cartId, params);
}
public Cart getCartByMarketAreaIdAndCustomerId(final Long marketAreaId, final Long customerId, Object... params) {
return cartDao.getCartByMarketAreaIdAndCustomerId(marketAreaId, customerId, params);
}
public Cart getCartById(final String rawCartId, Object... params) {
long cartId = -1;
try {
cartId = Long.parseLong(rawCartId);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(e);
}
return getCartById(cartId, params);
}
public Cart saveOrUpdateCart(Cart cart) {
return cartDao.saveOrUpdateCart(cart);
}
public void deleteCart(Cart cart) {
cartDao.deleteCart(cart);
}
public int deleteCart(final Timestamp before) {
return cartDao.deleteCart(before);
}
public String getCartTotalWithStandardCurrencySign(final Cart cart) {
return cart.getCurrency().formatPriceWithStandardCurrencySign(getCartTotal(cart));
}
public BigDecimal getCartTotal(final Cart cart) {
BigDecimal total = new BigDecimal(0);
Long marketAreaId = cart.getMarketAreaId();
for (CartItem cartItem : cart.getCartItems()) {
total = total.add(getCartItemTotalPriceWithTaxes(cartItem, marketAreaId));
}
return total;
}
public String getTaxTotalWithStandardCurrencySign(final Cart cart) {
return cart.getCurrency().formatPriceWithStandardCurrencySign(getTaxTotal(cart));
}
public String getCartItemTotalWithStandardCurrencySign(final Cart cart) {
return cart.getCurrency().formatPriceWithStandardCurrencySign(getCartItemTotal(cart));
}
public BigDecimal getCartItemTotal(final Cart cart) {
BigDecimal cartItemsTotal = new BigDecimal(0);
Long marketAreaId = cart.getMarketAreaId();
Set<CartItem> cartItems = cart.getCartItems();
if (cartItems != null && Hibernate.isInitialized(cartItems)) {
for (final CartItem cartItem : cartItems) {
cartItemsTotal = cartItemsTotal.add(getCartItemTotalPrice(cartItem, marketAreaId));
}
}
return cartItemsTotal;
}
public String getCartItemTotalWithTaxesWithStandardCurrencySign(final Cart cart) {
return cart.getCurrency().formatPriceWithStandardCurrencySign(getCartItemTotalWithTaxes(cart));
}
public BigDecimal getCartItemTotalWithTaxes(final Cart cart) {
BigDecimal cartItemsTotal = new BigDecimal(0);
Long marketAreaId = cart.getMarketAreaId();
Set<CartItem> cartItems = cart.getCartItems();
if (cartItems != null && Hibernate.isInitialized(cartItems)) {
for (final CartItem cartItem : cartItems) {
cartItemsTotal = cartItemsTotal.add(getCartItemTotalPriceWithTaxes(cartItem, marketAreaId));
}
}
return cartItemsTotal;
}
public String getCartItemPriceWithStandardCurrencySign(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return productSkuStorePrice.getCurrency().formatPriceWithStandardCurrencySign(cartItem.getCartItemPrice(productSkuStorePrice, cartItem.getTaxes()));
}
}
return null;
}
public BigDecimal getCartItemPrice(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return cartItem.getCartItemPrice(productSkuStorePrice, cartItem.getTaxes());
}
}
return null;
}
public String getCartItemPriceWithTaxesWithStandardCurrencySign(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return productSkuStorePrice.getCurrency().formatPriceWithStandardCurrencySign(cartItem.getCartItemPriceWithTaxes(productSkuStorePrice, cartItem.getTaxes()));
}
}
return null;
}
public BigDecimal getCartItemPriceWithTaxes(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return cartItem.getCartItemPriceWithTaxes(productSkuStorePrice, cartItem.getTaxes());
}
}
return null;
}
public String getCartItemTotalPriceWithStandardCurrencySign(final CartItem cartItem, final Long marketAreaId, final List<CartItemTax> taxes) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
BigDecimal result = cartItem.getCartItemPrice(productSkuStorePrice, taxes).multiply(new BigDecimal(cartItem.getQuantity()));
return productSkuStorePrice.getCurrency().formatPriceWithStandardCurrencySign(result);
}
}
return null;
}
public BigDecimal getCartItemTotalPrice(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return cartItem.getCartItemPrice(productSkuStorePrice, cartItem.getTaxes()).multiply(new BigDecimal(cartItem.getQuantity()));
}
}
return null;
}
public String getCartItemTotalPriceWithTaxesWithStandardCurrencySign(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
BigDecimal result = cartItem.getCartItemPriceWithTaxes(productSkuStorePrice, cartItem.getTaxes()).multiply(new BigDecimal(cartItem.getQuantity()));
return productSkuStorePrice.getCurrency().formatPriceWithStandardCurrencySign(result);
}
}
return null;
}
public BigDecimal getCartItemTotalPriceWithTaxes(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return cartItem.getCartItemPriceWithTaxes(productSkuStorePrice, cartItem.getTaxes()).multiply(new BigDecimal(cartItem.getQuantity()));
}
}
return null;
}
public Boolean isCartItemVATIncluded(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return productSkuStorePrice.isVATIncluded();
}
}
return null;
}
public BigDecimal getCartItemTaxesAmount(final CartItem cartItem, final Long marketAreaId) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
return cartItem.getCartItemTaxesAmount(productSkuStorePrice, cartItem.getQuantity(), cartItem.getTaxes());
}
}
return null;
}
public BigDecimal getTaxTotal(final Cart cart) {
BigDecimal total = new BigDecimal(0);
Long marketAreaId = cart.getMarketAreaId();
if (cart.getCartItems() == null || cart.getCartItems().isEmpty()) {
return total;
}
for (final CartItem cartItem : cart.getCartItems()) {
List<ProductSkuStorePrice> productSkuStorePrices = productDao.findProductSkuStorePrices(cartItem.getStoreId(), cartItem.getProductSku().getId());
for (ProductSkuStorePrice productSkuStorePrice : productSkuStorePrices) {
if (productSkuStorePrice.getMarketAreaId().equals(marketAreaId)) {
BigDecimal cartItemTaxesAmount = cartItem.getCartItemTaxesAmount(productSkuStorePrice, cartItem.getQuantity(), cartItem.getTaxes());
total = total.add(cartItemTaxesAmount);
break;
}
}
}
return total;
}
}