package org.multibit.mbm.core.model; import com.google.common.base.Preconditions; import org.joda.money.BigMoney; import org.multibit.mbm.utils.ObjectUtils; import javax.persistence.*; import java.io.Serializable; /** * <p> * DTO to provide the following to application:<br> * <ul> * <li>Stores state for a Cart Item (link between Cart and Item)</li> * </ul> * The CartItem describes the Items assigned to a particular Cart and any additional properties that are * specific to the relationship (for example the quantity of a given Item in the Cart). * </p> */ @Entity @Table(name = "cart_items") @AssociationOverrides({ @AssociationOverride( name = "primaryKey.item", joinColumns = @JoinColumn(name = "item_id")), @AssociationOverride( name = "primaryKey.cart", joinColumns = @JoinColumn(name = "cart_id")) }) public class CartItem implements Serializable { private static final long serialVersionUID = 389475903837482L; private CartItemPk primaryKey = new CartItemPk(); @Column(name = "quantity", nullable = false) private int quantity = 0; @Column(name = "index", nullable = false) private int index = 0; /** * Default constructor required by Hibernate */ public CartItem() { } /** * Standard constructor with mandatory fields * * @param cart required cart * @param item required item */ public CartItem(Cart cart, Item item) { Preconditions.checkNotNull(cart, "cart is required"); Preconditions.checkNotNull(item, "item is required"); primaryKey.setCart(cart); primaryKey.setItem(item); } /** * @return Returns the primary key */ @EmbeddedId public CartItemPk getPrimaryKey() { return primaryKey; } public void setPrimaryKey(CartItemPk primaryKey) { this.primaryKey = primaryKey; } /** * @return Returns primaryKey.getItem() */ @Transient public Item getItem() { return primaryKey.getItem(); } /** * @return Returns primaryKey.getCart() */ @Transient public Cart getCart() { return primaryKey.getCart(); } /** * @return The quantity of the Item (measured in the smallest divisible unit) */ public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } /** * @return The index position of the Item (zero-based) */ public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } /** * @return The stock-keeping unit (from primary key) */ @Transient public String getItemSKU() { return getItem().getSKU(); } /** * The price subtotal is the (quantity * price) * * @return The price subtotal */ @Transient public BigMoney getPriceSubtotal() { return getItem().getLocalPrice().multipliedBy(quantity); } /** * The tax subtotal is the (price subtotal * tax rate) * * @return The tax subtotal */ @Transient public BigMoney getTaxSubtotal() { return getPriceSubtotal().multipliedBy(getItem().getTaxRate()); } /** * The cart item subtotal is the (price subtotal + tax subtotal) * * @return The cart item subtotal */ @Transient public BigMoney getCartItemSubtotal() { return getPriceSubtotal().plus(getTaxSubtotal()); } /** * Primary key class to set the Cart and the Item as primary key in this many to many * relationship. */ @Embeddable public static class CartItemPk implements Serializable { private static final long serialVersionUID = 1L; private Item item; private Cart cart; /** * The associated Item * * @return returns the item */ @ManyToOne(targetEntity = Item.class) @JoinColumn(name = "item_id") public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } /** * The associated Cart * * @return Returns the Cart */ @ManyToOne(targetEntity = Cart.class) public Cart getCart() { return cart; } public void setCart(Cart cart) { this.cart = cart; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final CartItemPk other = (CartItemPk) obj; return ObjectUtils.isEqual( cart, other.cart, item, other.item ); } @Override public int hashCode() { return ObjectUtils.getHashCode(cart, item); } @Override public String toString() { return String.format("CartItemPk[cart=%s, item=%s]]", cart, item); } } }