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 Delivery Item (link between Delivery and Item)</li> * </ul> * The DeliveryItem describes the Items assigned to a particular Delivery and any additional properties that are * specific to the relationship (for example the quantity of a given Item in the Delivery). * </p> */ @Entity @Table(name = "delivery_items") @AssociationOverrides({ @AssociationOverride( name = "primaryKey.item", joinColumns = @JoinColumn(name = "item_id")), @AssociationOverride( name = "primaryKey.delivery", joinColumns = @JoinColumn(name = "delivery_id")) }) public class DeliveryItem implements Serializable { private static final long serialVersionUID = 389475903837482L; private DeliveryItemPk primaryKey = new DeliveryItemPk(); @Column(name = "quantity", nullable = false) private int quantity = 0; @Column(name = "supplier_sku", nullable = true) private String supplierSKU = ""; @Column(name = "supplier_gtin", nullable = true) private String supplierGTIN = ""; @Column(name = "batch_reference", nullable = true) private String batchReference = ""; /** * Default constructor required by Hibernate */ public DeliveryItem() { } /** * Standard constructor with mandatory fields * * @param delivery required delivery * @param item required item */ public DeliveryItem(Delivery delivery, Item item) { Preconditions.checkNotNull(delivery, "delivery is required"); Preconditions.checkNotNull(item, "item is required"); primaryKey.setDelivery(delivery); primaryKey.setItem(item); } /** * @return Returns the primary key */ @EmbeddedId public DeliveryItemPk getPrimaryKey() { return primaryKey; } public void setPrimaryKey(DeliveryItemPk primaryKey) { this.primaryKey = primaryKey; } /** * @return Returns primaryKey.getItem() */ @Transient public Item getItem() { return primaryKey.getItem(); } /** * @return Returns primaryKey.getDelivery() */ @Transient public Delivery getDelivery() { return primaryKey.getDelivery(); } /** * @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 Supplier SKU reference */ public String getSupplierSKU() { return supplierSKU; } public void setSupplierSKU(String supplierSKU) { this.supplierSKU = supplierSKU; } /** * @return The Supplier GTIN reference */ public String getSupplierGTIN() { return supplierGTIN; } public void setSupplierGTIN(String supplierGTIN) { this.supplierGTIN = supplierGTIN; } /** * @return The Supplier's batch reference for these Items in the Delivery */ public String getBatchReference() { return batchReference; } public void setBatchReference(String batchReference) { this.batchReference = batchReference; } /** * @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 delivery item subtotal is the (price subtotal + tax subtotal) * * @return The delivery item subtotal */ @Transient public BigMoney getDeliveryItemSubtotal() { return getPriceSubtotal().plus(getTaxSubtotal()); } /** * Primary key class to set the Delivery and the Item as primary key in this many to many * relationship. */ @Embeddable public static class DeliveryItemPk implements Serializable { private static final long serialVersionUID = 1L; private Item item; private Delivery delivery; /** * 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 Delivery * * @return Returns the Delivery */ @ManyToOne(targetEntity = Delivery.class) public Delivery getDelivery() { return delivery; } public void setDelivery(Delivery delivery) { this.delivery = delivery; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final DeliveryItemPk other = (DeliveryItemPk) obj; return ObjectUtils.isEqual( delivery, other.delivery, item, other.item ); } @Override public int hashCode() { return ObjectUtils.getHashCode(delivery, item); } @Override public String toString() { return String.format("DeliveryItemPk[delivery=%s, item=%s]]", delivery, item); } } }