001package scpc.model;
002
003import java.io.Serializable;
004import java.util.Objects;
005import scpc.Calculator;
006
007/**
008 * Bonus item of promotions.
009 * <br>優惠品項
010 *
011 * @author Kent Yeh
012 * @param <T> type of real bonus item.
013 */
014public class BonusItem<T> implements IItem<T> {
015
016    private final IRule<T> rule;
017    private final IItem<T> item;
018
019    private double fracQuantity = 0d;
020
021    public BonusItem(IRule<T> rule, IItem<T> item) {
022        this.rule = rule;
023        this.item = item;
024    }
025
026    /**
027     * @see IItem#getIdentity()
028     * @return
029     */
030    @Override
031    public Serializable getIdentity() {
032        return item.getIdentity();
033    }
034
035    /**
036     * @see IItem#as()
037     * @return
038     */
039    @Override
040    public T as() {
041        return item.as();
042    }
043
044    /**
045     * The quantity of bonus.
046     * <br>優惠數量
047     *
048     * @return The quantity of bonus.
049     */
050    @Override
051    public long getQuantity() {
052        return Math.round(Math.floor(this.fracQuantity));
053    }
054
055    /**
056     * Not supported.
057     * <br>方法不可使用
058     *
059     * @param quantity
060     */
061    @Override
062    public void setQuantity(long quantity) {
063        throw new UnsupportedOperationException("Not supported yet.");
064    }
065
066    /**
067     * The assoicate rule of this bonus.
068     * <br>產生本優惠的規類
069     *
070     * @return The assoicate rule of this bonus.
071     */
072    public IRule<T> getRule() {
073        return rule;
074    }
075
076    /**
077     * for {@link Calculator} use only.
078     *
079     * @return
080     */
081    public double getFracQuantity() {
082        return fracQuantity;
083    }
084
085    /**
086     * for {@link Calculator} use only.
087     *
088     * @param fracQuantity
089     * @return
090     */
091    public BonusItem<T> incFracQuantity(double fracQuantity) {
092        this.fracQuantity += fracQuantity;
093        item.setQuantity(getQuantity());
094        return this;
095    }
096
097    /**
098     * for {@link Calculator} use only.
099     *
100     * @param fracQuantity
101     */
102    public void setFracQuantity(double fracQuantity) {
103        this.fracQuantity = fracQuantity;
104        item.setQuantity(getQuantity());
105    }
106
107    /**
108     * @see IItem#getSalePrice()
109     * @return
110     */
111    @Override
112    public double getSalePrice() {
113        return item.getSalePrice();
114    }
115
116    /**
117     * @see IItem#getRegularPrice()
118     * @return
119     */
120    @Override
121    public double getRegularPrice() {
122        return item.getRegularPrice();
123    }
124
125    @Override
126    public int hashCode() {
127        int hash = 5;
128        hash = 11 * hash + Objects.hashCode(this.rule);
129        hash = 11 * hash + Objects.hashCode(this.item);
130        return hash;
131    }
132
133    @Override
134    public boolean equals(Object obj) {
135        if (this == obj) {
136            return true;
137        }
138        if (obj == null) {
139            return false;
140        }
141        if (!getClass().isAssignableFrom(obj.getClass())) {
142            return false;
143        }
144        final BonusItem other = (BonusItem) obj;
145        return Objects.equals(this.item.as(), other.as())
146                && getQuantity() == other.getQuantity();
147    }
148
149    @Override
150    public String toString() {
151        return item.toString();
152    }
153
154}