Product.java 8.93 KB
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.codecrew.moya.model;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.eclipse.persistence.annotations.OptimisticLocking;
import org.eclipse.persistence.annotations.OptimisticLockingType;
import org.eclipse.persistence.annotations.PrivateOwned;

/**
 * 
 */
@Entity
@Table(name = "products")
@OptimisticLocking(type = OptimisticLockingType.CHANGED_COLUMNS)
public class Product extends GenericEntity {

    private static final String PRODUCTFLAG_TABLE_PRODUCTID = "product_id";
    private static final String PRODUCTFLAG_TABLE_COLUMN = "productflags";
    private static final long serialVersionUID = 1L;
    public static final String EVENT_ID_COLUMN = "event_id";

    public static final Product EMPTY_PRODUCT = new Product("----");

    @ManyToOne()
    @JoinColumn(name = EVENT_ID_COLUMN, nullable = false)
    private LanEvent event;

    private String color;

    @Column(name = "product_name")
    private String name;
    @Column(name = "description")
    @Lob
    private String description;

    @Column(name = "price", nullable = false, precision = 24, scale = 4)
    private BigDecimal price = BigDecimal.ZERO;

    @Column(name = "buy_in_price", nullable = true, precision = 24, scale = 4)
    private BigDecimal buyInPrice = BigDecimal.ZERO;

    @Column(name = "sort", nullable = false)
    private int sort;

    @Column(name = "barcode")
    private String barcode;

    @Enumerated(EnumType.STRING)
    @PrivateOwned
    @ElementCollection()
    @CollectionTable(
            joinColumns = @JoinColumn(name = PRODUCTFLAG_TABLE_PRODUCTID, referencedColumnName = ID_COLUMN),
            uniqueConstraints = @UniqueConstraint(columnNames = { PRODUCTFLAG_TABLE_PRODUCTID, PRODUCTFLAG_TABLE_COLUMN }))
    @Column(name = PRODUCTFLAG_TABLE_COLUMN)
    private Set<ProductFlag> productFlags = new HashSet<ProductFlag>();

    @JoinColumn(name = "provided_role_id", referencedColumnName = Role.ID_COLUMN)
    @ManyToOne
    private Role provides;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
    private List<Place> places;

    @ManyToMany()
    private List<ProductLimitation> productLimits;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
    private List<AccountEvent> accountEvents;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
    private List<InventoryEvent> inventoryEvents;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "product_discounts",
            inverseJoinColumns = {
                    @JoinColumn(name = "discount_id", referencedColumnName = Discount.ID_COLUMN)
            },
            joinColumns = {
                    @JoinColumn(name = PRODUCTFLAG_TABLE_PRODUCTID, referencedColumnName = Product.ID_COLUMN)
            })
    private List<Discount> discounts;

    private BigDecimal vat = BigDecimal.ZERO;
    private String unitName = "";

    @ManyToMany()
    @JoinTable(name = "product_foodwavetemplate",
            joinColumns = {
                    @JoinColumn(name = PRODUCTFLAG_TABLE_PRODUCTID, referencedColumnName = Product.ID_COLUMN),
            },
            inverseJoinColumns = {
                    @JoinColumn(name = "food_wave_template_id", referencedColumnName = FoodWaveTemplate.ID_COLUMN)
            },
            uniqueConstraints = {
                    @UniqueConstraint(columnNames = { PRODUCTFLAG_TABLE_PRODUCTID, "food_wave_template_id" })
            })
    private List<FoodWaveTemplate> foodWaveTemplates;

    public Product() {
        super();
    }

    public Product(LanEvent event) {
        super();
        this.setEvent(event);

    }

    private Product(String string) {
        super();
        name = "----";
    }

    public BigDecimal getSoldCash() {
        BigDecimal tot = BigDecimal.ZERO;
        for (AccountEvent ac : this.getAccountEvents()) {
            if (ac.isCash()) {
                tot = tot.add(ac.getQuantity());
            }
        }
        return tot;
    }

    public BigDecimal getSoldBill() {
        BigDecimal tot = BigDecimal.ZERO;
        for (AccountEvent ac : this.getAccountEvents()) {
            if (!ac.isCash()) {
                tot = tot.add(ac.getQuantity());
            }
        }
        return tot;
    }

    // TODO: alennukset lasketaan täällä. HUOMHUOM!!
    public List<Discount> getActiveDiscounts(BigDecimal quantity, Calendar time) {
        ArrayList<Discount> ret = new ArrayList<Discount>();
        for (Discount d : getDiscounts()) {
            if (d.isActive() &&
                    (d.getValidTo() == null || d.getValidTo().after(time)) &&
                    (d.getValidFrom() == null || d.getValidFrom().before(time)) &&
                    quantity.compareTo(d.getAmountMax()) <= 0 &&
                    quantity.compareTo(d.getAmountMin()) >= 0) {
                ret.add(d);
            }
        }
        return ret;
    }

    public BigDecimal getInventoryCount() {
        BigDecimal ret = new BigDecimal(0);

        if (accountEvents != null) {
            for (AccountEvent ae : accountEvents) {
                ret = ret.subtract(ae.getQuantity());
            }
        }
        if (inventoryEvents != null) {
            for (InventoryEvent ie : inventoryEvents) {
                ret = ret.add(ie.getQuantity());
            }
        }

        return ret;
    }

    public String getName() {
        return name;
    }

    public void setName(String productName) {
        this.name = productName;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public int getSort() {
        return sort;
    }

    public void setSort(int sort) {
        this.sort = sort;
    }

    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode;
    }

    public List<Place> getPlaces() {
        return places;
    }

    public void setPlaces(List<Place> placeList) {
        this.places = placeList;
    }

    public List<AccountEvent> getAccountEvents() {
        return accountEvents;
    }

    public void setAccountEvents(List<AccountEvent> accountEventList) {
        this.accountEvents = accountEventList;
    }

    public void setDiscounts(List<Discount> discounts) {
        this.discounts = discounts;
    }

    public List<Discount> getDiscounts() {
        return discounts;
    }

    public void setFoodWaveTemplates(List<FoodWaveTemplate> foodWaveTemplates) {
        this.foodWaveTemplates = foodWaveTemplates;
    }

    public List<FoodWaveTemplate> getFoodWaveTemplates() {
        return foodWaveTemplates;
    }

    public void setVat(BigDecimal vat) {
        this.vat = vat;
    }

    public BigDecimal getVat() {
        return vat;
    }

    public void setUnitName(String unitName) {
        this.unitName = unitName;
    }

    public String getUnitName() {
        return unitName;
    }

    public void setProvides(Role provides) {
        this.provides = provides;
    }

    public Role getProvides() {
        return provides;
    }

    public LanEvent getEvent() {
        return event;
    }

    public void setEvent(LanEvent event) {
        this.event = event;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Set<ProductFlag> getProductFlags() {
        return productFlags;
    }

    public void setProductFlags(Set<ProductFlag> productFlags) {
        this.productFlags = productFlags;
    }

    public List<ProductLimitation> getProductLimits() {
        return productLimits;
    }

    public void setProductLimits(List<ProductLimitation> productLimits) {
        this.productLimits = productLimits;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public BigDecimal getBuyInPrice() {
        return buyInPrice;
    }

    public void setBuyInPrice(BigDecimal buyInPrice) {
        this.buyInPrice = buyInPrice;
    }

    public List<InventoryEvent> getInventoryEvents() {
        return inventoryEvents;
    }

    public void setInventoryEvents(List<InventoryEvent> inventoryEvents) {
        this.inventoryEvents = inventoryEvents;
    }

}