package org.multibit.mbm.core.model;
import com.google.common.base.Preconditions;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Type;
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 PurchaseOrderItem (link between Purchase Order and Item)</li>
* </ul>
* The PurchaseOrderItem describes the Items assigned to a particular PurchaseOrder and any additional properties that are
* specific to the relationship (for example the quantity of a given Item in the PurchaseOrder).
* </p>
*/
@Entity
@Table(name = "purchase_order_items")
@AssociationOverrides({
@AssociationOverride(
name = "primaryKey.item",
joinColumns = @JoinColumn(name = "item_id")),
@AssociationOverride(
name = "primaryKey.purchase_order",
joinColumns = @JoinColumn(name = "purchase_order_id"))
})
public class PurchaseOrderItem implements Serializable {
private static final long serialVersionUID = 389475903837482L;
private PurchaseOrderItemPk primaryKey = new PurchaseOrderItemPk();
@Column(name = "quantity", nullable = false)
private int quantity = 0;
@Columns(columns = {
@Column(name = "unit_price_amount"),
@Column(name = "unit_price_currency")
})
@Type(type = "org.multibit.mbm.db.dao.hibernate.type.BigMoneyType")
private BigMoney unitPrice;
@Columns(columns = {
@Column(name = "unit_tax_amount"),
@Column(name = "unit_tax_currency")
})
@Type(type = "org.multibit.mbm.db.dao.hibernate.type.BigMoneyType")
private BigMoney unitTax;
@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 PurchaseOrderItem() {
}
/**
* Standard constructor with mandatory fields
*
* @param purchaseOrder required purchaseOrder
* @param item required item
*/
public PurchaseOrderItem(PurchaseOrder purchaseOrder, Item item) {
Preconditions.checkNotNull(purchaseOrder, "purchaseOrder is required");
Preconditions.checkNotNull(item, "item is required");
primaryKey.setPurchaseOrder(purchaseOrder);
primaryKey.setItem(item);
}
/**
* @return Returns the primary key
*/
@EmbeddedId
public PurchaseOrderItemPk getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(PurchaseOrderItemPk primaryKey) {
this.primaryKey = primaryKey;
}
/**
* @return Returns primaryKey.getItem()
*/
@Transient
public Item getItem() {
return primaryKey.getItem();
}
/**
* @return Returns primaryKey.getPurchaseOrder()
*/
@Transient
public PurchaseOrder getPurchaseOrder() {
return primaryKey.getPurchaseOrder();
}
/**
* @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 PurchaseOrder
*/
public String getBatchReference() {
return batchReference;
}
public void setBatchReference(String batchReference) {
this.batchReference = batchReference;
}
/**
* @return The unit price
*/
public BigMoney getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(BigMoney unitPrice) {
this.unitPrice = unitPrice;
}
/**
* @return The unit tax
*/
public BigMoney getUnitTax() {
return unitTax;
}
public void setUnitTax(BigMoney unitTax) {
this.unitTax = unitTax;
}
/**
* @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 purchaseOrder item subtotal is the (price subtotal + tax subtotal)
*
* @return The purchaseOrder item subtotal
*/
@Transient
public BigMoney getPurchaseOrderItemSubtotal() {
return getPriceSubtotal().plus(getTaxSubtotal());
}
/**
* Primary key class to set the PurchaseOrder and the Item as primary key in this many to many
* relationship.
*/
@Embeddable
public static class PurchaseOrderItemPk implements Serializable {
private static final long serialVersionUID = 1L;
private Item item;
private PurchaseOrder purchaseOrder;
/**
* 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 PurchaseOrder
*
* @return Returns the PurchaseOrder
*/
@ManyToOne(targetEntity = PurchaseOrder.class)
public PurchaseOrder getPurchaseOrder() {
return purchaseOrder;
}
public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
this.purchaseOrder = purchaseOrder;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PurchaseOrderItemPk other = (PurchaseOrderItemPk) obj;
return ObjectUtils.isEqual(
purchaseOrder, other.purchaseOrder,
item, other.item
);
}
@Override
public int hashCode() {
return ObjectUtils.getHashCode(purchaseOrder, item);
}
@Override
public String toString() {
return String.format("PurchaseOrderItemPk[purchaseOrder=%s, item=%s]]", purchaseOrder, item);
}
}
}