Moneyタイプのパッケージ

8211 ワード

public class Money extends Quantity<Currency> {
	private static final long serialVersionUID = 4586753888134642487L;
	
	private static final Currency DEFAULT_CURRENCY = Currency.getInstance("CNY");
	private static final int DEFAULT_SCALE = 2;
	
	public static final Money ZERO = new Money();
	public static final Money ONE_CHIAO = new Money(DEFAULT_CURRENCY, new BigDecimal("0.1"));
	public static final Money ONE_YUAN = new Money(DEFAULT_CURRENCY, new BigDecimal("1"));
	
    public Money() {
        this(DEFAULT_CURRENCY, new BigDecimal(0));
	}

    public static Money getZero(){
    	return ZERO;
    }
	public Money(Currency currency, BigDecimal amount) {
		super();
		setUnits(currency);
		setAmount(amount);
	}

	public Money(Quantity<Currency> quantity) {
		this(quantity.getUnits(),
				new BigDecimal(quantity.getAmount().toString()));
	}

	public Money(BigDecimal amount) {
		this(DEFAULT_CURRENCY, amount);
	}

	public Money(double amount) {
		this(DEFAULT_CURRENCY, new BigDecimal(amount));
	}

	public void setAmount(BigDecimal amount) {
		super.setAmount(amount.setScale(DEFAULT_SCALE, RoundingMode.HALF_UP));
	}
	
	public BigDecimal getAmount() {
		return ((BigDecimal)super.getAmount()).setScale(DEFAULT_SCALE, RoundingMode.HALF_UP);
	}

	/**
	 *  
	 */
	public Quantity<Currency> plus(Quantity<Currency> another){
		return plus((Money)another);
	}
    
	/**
	 *  
	 */
	public Money plus(Money another) {
		BigDecimal amount = this.getAmount().add(another.getAmount());
		return new Money(this.getUnits(),amount);
	}
    
	/**
	 *  
	 */
	public Money plus(BigDecimal another) {
		return new Money(this.getUnits(),this.getAmount().add(another));
	}
	
	/**
	 *  
	 */
    public Money plus(double another) {
        return plus(new Money(another));
    }
	
	/**
	 *  
	 */
	public Quantity<Currency> minus(Quantity<Currency> another){
		return minus((Money)another);
	}

	/**
	 *  
	 */
	public Money minus(Money another) {
		BigDecimal amount = this.getAmount().subtract(another.getAmount());
		return new Money(this.getUnits(),amount);
	}

	/**
	 *  
	 */
    public Money minus(double another) {
        return minus(new Money(another));
    }

	/**
	 *  
	 */
	public Money multiply(BigDecimal another) {
		BigDecimal amount = this.getAmount().multiply(another);
		return new Money(this.getUnits(), amount);
	}

	/**
	 *  
	 */
	public Money multiply(double another) {
		return this.multiply(new BigDecimal(another));
	}
	
	/**
	 *  
	 */
	public Money divide(BigDecimal divisor) {
		BigDecimal amount = this.getAmount().divide(divisor, DEFAULT_SCALE, RoundingMode.HALF_UP);
		return new Money(this.getUnits(), amount);
	}
	
	/**
	 *  
	 */
	public Money divide(double divisor) {
		return this.divide(new BigDecimal(divisor));
	}

	/**
	 *  
	 */
	public Money negative() {
		return new Money().minus(this);
	}
	
	/**
	 *  
	 */
	public Money abs() {
		return new Money(this.getAmount().abs());
	}
	
	/**
	 *  
	 */
	public Money floorChiao() {
		double amount = Math.floor(getAmount().doubleValue());
		return new Money(this.getUnits(), new BigDecimal(amount));
	}
	
	/**
	 *  
	 */
	public Money floorCent() {
		double amount = Math.floor(getAmount().doubleValue() * 10);
		amount = amount / 10;
		return new Money(this.getUnits(), new BigDecimal(amount));
	}
	
	/**
	 *  
	 */
	public Money ceilCent() {
		double amount = Math.ceil(getAmount().doubleValue() * 10);
		amount = amount / 10;
		return new Money(this.getUnits(), new BigDecimal(amount));
	}
	
	/**
	 *  
	 */
	public Money ceilChiao() {
		double amount = Math.ceil(getAmount().doubleValue());
		return new Money(this.getUnits(), new BigDecimal(amount));
	}

	protected BigDecimal computeRate(Currency another) {
		BigDecimal rate = new BigDecimal("1.0");
		// 
		if (!this.getUnits().equals(another)) {
			// TODO  
		}else{
			rate = new BigDecimal("1.0");
		}
		return rate;
	}

	@Override
	public Money clone() {
		return new Money(this);
	}

	public int compareTo(Quantity<Currency> other) {
		assert other instanceof Money : "Money Money ";
		Money money = (Money) other;
		BigDecimal difference = this.getAmount().multiply(computeRate(this.getUnits()))
				.subtract(money.getAmount().multiply(computeRate(money.getUnits())));
		if (difference.abs().setScale(DEFAULT_SCALE, RoundingMode.HALF_UP)
				.multiply(new BigDecimal("100")).intValue() < 1)
			return 0;
		else
			return difference.signum();
	}

	@Override
	public boolean equals(Object other) {
		if(!(other instanceof Money))
			return false;
		
		if (compareTo((Money)other) == 0)
			return true;
		else
			return false;
	}

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(getAmount().toPlainString());
		return sb.toString();
	}
}

 
public abstract class Quantity<T> extends BaseBean implements Serializable, Comparable<Quantity<T>> {
	private static final long serialVersionUID = 7300915847975292623L;
	
	private T units;
	public Number amount;
	
	protected Quantity() {
		super();
		
	}

	public Quantity(T units, Number amount) {
		assert units != null : " ";
		this.units = units;
		this.amount = amount;
	}

	public Number getAmount() {
		return amount;
	}

	public void setAmount(Number amount) {
		Object oldAmount = this.amount;
		this.amount = amount;
		firePropertyChange("amount", oldAmount, amount);
	}

	public T getUnits() {
		return units;
	}
	
	public void setUnits(T units) {
		this.units = units;
	}

	/**
	 *  
	 */
	public Quantity<T> plus(Quantity<T> another){
		throw new UnsupportedOperationException(" ");
	}
	
	/**
	 *  
	 */
	public Quantity<T> minus(Quantity<T> another){
		throw new UnsupportedOperationException(" ");
	}

	/**
	 *  
	 */
	public Quantity<T> multiply(BigDecimal another) {
		throw new UnsupportedOperationException(" ");
	}

	public Quantity<T> multiply(double another) {
		throw new UnsupportedOperationException(" ");
	}
	
	/**
	 *  
	 */
	public Quantity<T> negative() {
		throw new UnsupportedOperationException(" ");
	}

	@SuppressWarnings("unchecked")
    @Override
	public boolean equals(Object other) {
		if (!(other instanceof Quantity))
			return false;
		
		Quantity<T> otherQuantity = (Quantity<T>) other;
		
		return this.compareTo(otherQuantity) == 0;
	}
	
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(getAmount());
		sb.append(getUnits());
		return sb.toString();
	}


}