/*******************************************************************************
* Copyright (c) 2015 XLAB d.o.o.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* @author XLAB d.o.o.
*******************************************************************************/
package eu.cloudscale.showcase.db.services;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import br.ufrgs.inf.prosoft.cache.*;
import eu.cloudscale.showcase.db.BuyConfirmResult;
import eu.cloudscale.showcase.db.common.ContextHelper;
import eu.cloudscale.showcase.db.dao.IAddressDao;
import eu.cloudscale.showcase.db.dao.IAuthorDao;
import eu.cloudscale.showcase.db.dao.ICcXactsDao;
import eu.cloudscale.showcase.db.dao.ICountryDao;
import eu.cloudscale.showcase.db.dao.ICustomerDao;
import eu.cloudscale.showcase.db.dao.IItemDao;
import eu.cloudscale.showcase.db.dao.IOrderLineDao;
import eu.cloudscale.showcase.db.dao.IOrdersDao;
import eu.cloudscale.showcase.db.dao.IShoppingCartDao;
import eu.cloudscale.showcase.db.dao.IShoppingCartLineDao;
import eu.cloudscale.showcase.db.dao.mongo.impl.ShoppingCartDaoImpl;
import eu.cloudscale.showcase.db.model.IAddress;
import eu.cloudscale.showcase.db.model.IAuthor;
import eu.cloudscale.showcase.db.model.ICcXacts;
import eu.cloudscale.showcase.db.model.ICountry;
import eu.cloudscale.showcase.db.model.ICustomer;
import eu.cloudscale.showcase.db.model.IItem;
import eu.cloudscale.showcase.db.model.IOrderLine;
import eu.cloudscale.showcase.db.model.IOrders;
import eu.cloudscale.showcase.db.model.IShoppingCart;
import eu.cloudscale.showcase.db.model.IShoppingCartLine;
import eu.cloudscale.showcase.db.model.hibernate.ShoppingCart;
@Transactional(readOnly=true)
public abstract class AService implements IService
{
@Autowired
protected IAddressDao addressDao;
@Autowired
protected IAuthorDao authorDao;
@Autowired
protected ICcXactsDao ccXactsDao;
@Autowired
protected ICountryDao countryDao;
@Autowired
protected ICustomerDao customerDao;
@Autowired
protected IItemDao itemDao;
@Autowired
protected IOrderLineDao orderLineDao;
@Autowired
protected IOrdersDao ordersDao;
@Autowired
protected IShoppingCartDao shoppingCartDao;
@Autowired
protected IShoppingCartLineDao shoppingCartLineDao;
@Override
@Transactional(readOnly=false)
public IShoppingCart createEmptyCart()
{
IShoppingCartDao scDao = shoppingCartDao;
IShoppingCart sc = new ShoppingCart();
sc.setScTime( new Date() );
//getCurrentSession().saveOrUpdate(sc);
scDao.shrani( sc );
return sc;
}
public static Caffeine<String, List> getNewProductsCache = new Caffeine<>("static-multi:AService.getNewProducts", 86400000);
@SuppressWarnings( "rawtypes" )
@Override
// @Cacheable("newProducts")
public List getNewProducts(String category)
{
return getNewProductsCache.computeIfAbsent(category, () -> {
//System.out.println("getNewProducts(" + category + ") called!");
return itemDao.getNewProducts( category );
}, 86400000);
}
@Override
@Transactional(readOnly=false)
public IShoppingCart doCart(IShoppingCart sc, Integer itemId,
List<Integer> ids, List<Integer> quantities)
{
IShoppingCartLineDao sclDao = shoppingCartLineDao;
IShoppingCartDao scDao = shoppingCartDao;
if ( itemId != null )
{
addItem( sc, itemDao.findById( itemId.intValue() ) );
}
refreshCart( sc, ids, quantities );
addRandomItemToCartIfNecessary( sc );
resetCartTime( sc );
//System.out.println("[scDao.shrani] doCart()");
scDao.shrani(sc, true);
return sc;
}
public void resetCartTime(IShoppingCart sc)
{
try
{
sc.setScTime( new Date() );
}
catch(Exception e)
{
System.out.println("ShoppingId = " + sc.getScId());
e.printStackTrace();
}
}
//@Transactional(readOnly=false)
public void addRandomItemToCartIfNecessary(IShoppingCart sc)
{
// check and see if the cart is empty. If it's not, we do
// nothing.
try
{
// Check to see if the cart is empty
if ( sc.getShoppingCartLines().size() == 0 )
{
// Cart is empty
addItem( sc, itemDao.getRandomItem() );
}
}
catch ( java.lang.Exception ex )
{
ex.printStackTrace();
}
}
protected IShoppingCart getCart(Integer shoppingId, double discount)
{
IShoppingCartDao scDao = shoppingCartDao;
IShoppingCart sc = scDao.findById( shoppingId );
return sc;
}
// protected void addRandomItemToCartIfNecessary(
// IShoppingCartLineDao sclDao, Integer shoppingId)
// {
// IItemDao itemDao = getItemDaoImpl();
//
// if ( sclDao.isCartEmpty( shoppingId ) )
// {
// IItem randItem = itemDao.getRandomItem();
// // related_item = getRelated1(sclDao, shoppingId, randItem);
// addItem( shoppingId, randItem );
// }
//
// }
// protected IItem getRelated1(IShoppingCartLineDao<IShoppingCartLine>
// sclDao,
// Integer shoppingId,
// IItem randItem)
// {
// IItemDao<IItem> itemDao = getItemDaoImpl();
// IItem relatedItem = itemDao.getRelated1( randItem );
// return relatedItem;
// }
//@Transactional(readOnly=false)
public void refreshCart(IShoppingCart sc, List<Integer> ids,
List<Integer> quantities)
{
IShoppingCartLineDao sclDao = shoppingCartLineDao;
for ( int i = 0; i < ids.size(); i++ )
{
int itemId = ids.get( i );
int QTY = quantities.get( i );
IShoppingCartLine scl = sclDao.getBySCandItem( sc.getScId(), itemId );
if ( QTY == 0 )
{
//System.out.println("[sclDao.delete] addItem()");
sclDao.delete( scl );
}
else
{
scl.setSclQty( QTY );
//System.out.println("[sclDao.shrani] refreshCart()");
sclDao.shrani( scl );
}
}
}
//@Transactional(readOnly=false)
public void addItem(IShoppingCart sc, IItem item)
{
IShoppingCartLineDao sclDao = shoppingCartLineDao;
IShoppingCartDao scDao = shoppingCartDao;
IShoppingCartLine scl = sclDao.getBySCandItem( sc.getScId(),
item.getIId() );
if ( scl != null )
{
scl.setSclQty( scl.getSclQty() + 1 );
//System.out.println("[sclDao.shrani] addItem()");
sclDao.shrani( scl );
}
else
{
scl = sclDao.getObject();
scl.setItem( item );
scl.setSclQty( 1 );
scl.setShoppingCart( sc );
//System.out.println("[sclDao.shrani] addItem()");
sclDao.shrani( scl );
sc.getShoppingCartLines().add( scl );
//scDao.shrani( sc );
}
}
@Override
@Transactional(readOnly=false)
public BuyConfirmResult doBuyConfirm(Integer shoppingId,
Integer customerId, String ccType, long ccNumber, String ccName,
Date ccExpiry, String shipping, String street1, String street2,
String city, String state, String zip, String country)
{
IShoppingCart sc = shoppingCartDao.findById( shoppingId );
if( sc != null)
{
ICustomer customer = customerDao.findById( customerId );
double cDiscount = getCDiscount( customer );
// IShoppingCart cart = getCart( shoppingId, cDiscount );
IAddress address = saveAddress( street1, street2, city, state, zip,
country );
IOrders order = saveOrder( address, customer, shipping, sc, cDiscount );
saveCcXacts( order, ccType, ccNumber, ccName, ccExpiry, sc, address );
clearCart( shoppingId );
return new BuyConfirmResult( order, sc );
}
return new BuyConfirmResult(null, null);
}
@Override
@Transactional(readOnly=false)
public BuyConfirmResult doBuyConfirm(Integer shoppingId,
Integer customerId, String ccType, Long ccNumber, String ccName,
Date ccExpiry, String shipping)
{
ICustomer customer = customerDao.findById( customerId );
double discount = getCDiscount( customer );
IShoppingCart sc = getCart( shoppingId, discount );
if( sc != null)
{
IAddress address = customer.getAddress();
IOrders order = saveOrder( address, customer, shipping, sc, discount );
saveCcXacts( order, ccType, ccNumber, ccName, ccExpiry, sc, address );
clearCart( shoppingId );
return new BuyConfirmResult( order, sc );
}
return new BuyConfirmResult( null, null );
}
@Transactional(readOnly=false)
protected void clearCart(Integer shoppingId)
{
IShoppingCartDao scDao = shoppingCartDao;
IShoppingCart sc = (IShoppingCart) scDao.findById( shoppingId );
IShoppingCartLineDao sclDao = shoppingCartLineDao;
Set<IShoppingCartLine> res = sc.getShoppingCartLines();
if( res != null && !res.isEmpty() )
{
for ( IShoppingCartLine scl : res )
{
sclDao.delete( scl );
}
}
}
@Transactional(readOnly=false)
protected ICcXacts saveCcXacts(IOrders order, String ccType, long ccNumber,
String ccName, Date ccExpiry, IShoppingCart cart, IAddress address)
{
if ( ccType.length() > 10 )
ccType = ccType.substring( 0, 10 );
if ( ccName.length() > 30 )
ccName = ccName.substring( 0, 30 );
ICcXacts ccXacts = ccXactsDao.getObject();
ccXacts.setCountry( address.getCountry() );
ccXacts.setOrders( order );
ccXacts.setCxType( ccType );
ccXacts.setCxNum( (int) ccNumber );
ccXacts.setCxName( ccName );
ccXacts.setCxExpiry( ccExpiry );
ccXacts.setCxXactAmt( calculateTotal( cart ) );
ccXacts.setCxXactDate( new Date() );
ccXacts.setCountry( address.getCountry() );
ccXactsDao.shrani( ccXacts );
return ccXacts;
}
@Transactional(readOnly=false)
protected IAddress saveAddress(String street1, String street2, String city,
String state, String zip, String country)
{
IAddress address = addressDao.getObject();
address.setAddrStreet1( street1 );
address.setAddrStreet2( street2 );
address.setAddrCity( city );
address.setAddrState( state );
address.setAddrZip( zip );
address.setCountry( countryDao.getByName( country ) );
addressDao.shrani( address );
return address;
}
@Transactional(readOnly=false)
protected IOrders saveOrder(IAddress address, ICustomer customer,
String shipping, IShoppingCart sc, double discount)
{
Calendar cal = Calendar.getInstance();
Random rand = new Random();
IOrders order = ordersDao.getObject();
order.setCustomer( customer );
order.setOTax( 8.25 );
order.setODate( new Date() );
order.setAddressByOBillAddrId( customer.getAddress() );
order.setAddressByOShipAddrId( address );
cal.add( Calendar.DATE, rand.nextInt( 7 ) );
order.setOShipDate( cal.getTime() );
order.setOShipType( shipping );
order.setOStatus( "PENDING" );
order.setOTotal( calculateTotal( sc ) );
order.setOSubTotal( calculateTotal( sc ) );
ordersDao.shrani( order );
Set<IShoppingCartLine> res = sc.getShoppingCartLines();
if( res != null && !res.isEmpty() )
{
for ( IShoppingCartLine scl : res)
{
IOrderLine ol = orderLineDao.getObject();
ol.setItem( scl.getItem() );
ol.setOlComment( getRandomString( 20, 100 ) );
ol.setOlDiscount( discount );
ol.setOlQty( scl.getSclQty() );
ol.setOrders( order );
order.getOrderLines().add( ol );
orderLineDao.shrani( ol );
}
}
ordersDao.shrani( order );
return order;
}
public String getRandomString(int min, int max)
{
String newstring = new String();
Random rand = new Random();
int i;
final char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^',
'&', '*', '(', ')', '_', '-', '=', '+', '{', '}', '[', ']',
'|', ':', ';', ',', '.', '?', '/', '~', ' ' }; // 79
// characters
int strlen = (int) Math.floor( rand.nextDouble() * ( max - min + 1 ) );
strlen += min;
for ( i = 0; i < strlen; i++ )
{
char c = chars[(int) Math.floor( rand.nextDouble() * 79 )];
newstring = newstring.concat( String.valueOf( c ) );
}
return newstring;
}
protected double calculateTotal(IShoppingCart sc)
{
double total = 0;
if( sc != null )
{
Set<IShoppingCartLine> res = sc.getShoppingCartLines();
if( res != null && !res.isEmpty() )
{
for ( IShoppingCartLine scl : res )
{
if( scl != null )
{
total += scl.getItem().getICost();
}
}
}
}
return total;
}
protected double getCDiscount(ICustomer customer)
{
return customer.getCDiscount();
}
@Override
public List searchByAuthor(String keyword)
{
List<IAuthor> authors = authorDao.findBySoundexLname( keyword );
List<IItem> items = new ArrayList<IItem>();
for ( IAuthor author : authors )
{
if ( items.size() >= 50 )
{
break;
}
items.addAll( itemDao.findAllByAuthor( author ) );
}
return items;
}
@Override
public List<IItem> getPromotional()
{
return itemDao.getPromotional();
}
@Override
public boolean countryExist( String country)
{
ICountry country1 = countryDao.getByName( country );
return country1 == null;
}
@Override
public ICustomer getUserBy(String uname, String passwd)
{
return customerDao.getUserBy( uname, passwd );
}
@Override
public ICustomer getCustomerObject()
{
return customerDao.getObject();
}
@Override
public IAddress getAddressObject()
{
return addressDao.getObject();
}
@Override
public ICountry getCountryByName(String country)
{
return countryDao.getByName( country );
}
@Override
@Transactional(readOnly=false)
public void saveAddress(IAddress address)
{
addressDao.shrani(address);
}
@Override
@Transactional(readOnly=false)
public void saveCustomer(ICustomer customer)
{
customerDao.shrani( customer );
}
@Override
public IShoppingCart findShoppingCartById(Integer shoppingId)
{
return shoppingCartDao.findById( shoppingId );
}
@Override
public ICustomer findCustomerById(Integer customerId)
{
return customerDao.findById( customerId );
}
public static Caffeine<String, List<Object[]>> getBestSellersCache = new Caffeine<>("static-multi:AService.getBestSellers", 86400000);
@Override
// @Cacheable("bestSellers")
public List<Object[]> getBestSellers(String category)
{
return getBestSellersCache.computeIfAbsent(category, () -> {
//System.out.println("getNewProducts(" + category + ") called!");
return itemDao.getBestSellers( category );
}, 86400000);
}
public static Caffeine<String, List<IItem>> searchByTitleCache = new Caffeine<>("static-multi:AService.searchByTitle", 86400000);
@Override
// @Cacheable("search")
public List<IItem> searchByTitle(String keyword)
{
return searchByTitleCache.computeIfAbsent(keyword, () -> {
List<IItem> items = itemDao.findAllByTitle( keyword );
return items;
}, 86400000);
}
public static Caffeine<String, List<IItem>> searchBySubjectCache = new Caffeine<>("static-multi:AService.searchBySubject", 86400000);
@Override
// @Cacheable("search")
public List<IItem> searchBySubject(String keyword)
{
return searchBySubjectCache.computeIfAbsent(keyword, () -> {
List<IItem> items = itemDao.findAllBySubject( keyword );
return items;
}, 86400000);
}
@Override
public IOrders getMostRecentOrder(ICustomer customer)
{
return ordersDao.getMostRecentOrder( customer );
}
@Override
public List<IOrderLine> findAllOrderLineByOrder(IOrders order)
{
return orderLineDao.findAllByOrder( order );
}
@Override
public IItem findItemById(Integer itemId)
{
return itemDao.findById( itemId );
}
@Override
public IAddress findAddressById(Integer addrId)
{
return addressDao.findById( addrId );
}
@Override
public ICountry getCountryById(Integer coId)
{
return countryDao.findById( coId );
}
@Override
public List<ICustomer> findCustomerByAddress(IAddress address)
{
return customerDao.findByAddress( address );
}
@Override
public IOrders findOrdersById(Integer cxOId)
{
return ordersDao.findById( cxOId );
}
@Override
public IAuthor findAuthorById(Integer cxAuthId)
{
try
{
return authorDao.findById( cxAuthId );
}
catch(Exception e)
{
System.out.println("AuthorDao is null");
return null;
}
}
@Override
public IOrderLine findOrderLineById(Integer olId)
{
return orderLineDao.findById( olId );
}
@Override
public ICcXacts findCcXactsById(Integer ccXactId)
{
return ccXactsDao.findById( ccXactId );
}
@Override
public List findAllShoppingCartLinesBySC(IShoppingCart shoppingCart)
{
try
{
return shoppingCartDao.findAllBySC( shoppingCart );
}
catch(NullPointerException e)
{
e.printStackTrace();
return null;
}
}
@Override
@Transactional(readOnly=false)
public void saveItem(IItem item) {
itemDao.shrani(item);
}
}