001/* Copyright (C) 2014 konik.io
002 *
003 * This file is part of the Konik library.
004 *
005 * The Konik library is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * The Konik library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with the Konik library. If not, see <http://www.gnu.org/licenses/>.
017 */
018package io.konik.util;
019
020
021import com.neovisionaries.i18n.CurrencyCode;
022import io.konik.zugferd.unqualified.Amount;
023
024import java.math.BigDecimal;
025import java.math.RoundingMode;
026
027/**
028 * Helper functions for {@link Amount} class.
029 */
030public final class Amounts {
031
032        /**
033         * Creates {@link Amount} object with 0 (zero) value and given {@link CurrencyCode}
034         * @param currencyCode
035         * @return
036         */
037        public static Amount zero(CurrencyCode currencyCode) {
038                return new Amount(BigDecimal.ZERO, currencyCode);
039        }
040
041        /**
042         * Sums two amounts with the same {@link CurrencyCode} and throws {@link IllegalArgumentException} if
043         * amounts don't have the same {@link CurrencyCode}
044         * @param first
045         * @param second
046         * @return
047         */
048        public static Amount add(final Amount first, final Amount second) {
049                if (first == null && second == null) {
050                        throw new IllegalArgumentException("First and second amount cannot be null");
051                }
052
053                if (first != null && second != null && !first.getCurrency().equals(second.getCurrency())) {
054                        throw new IllegalArgumentException("Cannot add two amounts with different currencies");
055                }
056
057                CurrencyCode currency = first != null ? first.getCurrency() : second.getCurrency();
058                BigDecimal firstValue = first != null ? first.getValue() : BigDecimal.ZERO;
059                BigDecimal secondValue = second != null ? second.getValue() : BigDecimal.ZERO;
060
061                return new Amount(firstValue.add(secondValue), currency);
062        }
063
064        /**
065         * Multiplies given {@link Amount} specified number of times.
066         * @param amount
067         * @param times
068         * @return
069         */
070        public static Amount multiply(Amount amount, BigDecimal times) {
071                return new Amount(amount.getValue().multiply(times), amount.getCurrency());
072        }
073
074        /**
075         * Negate Amount
076         *
077         * @param amount the amount
078         * @return the amount
079         */
080        public static Amount negate(Amount amount) {
081                return new Amount(amount.getValue().negate(), amount.getCurrency());
082        }
083
084        /**
085         * Amount absolute value.
086         * @param amount
087         * @return
088         */
089        public static Amount abs(Amount amount) {
090                return new Amount(amount.getValue().abs(), amount.getCurrency());
091        }
092
093        /**
094         * Sets the precision for amount.
095         *
096         * @param amount the amount
097         * @param precision the precision
098         * @param roundingMode the rounding mode
099         * @return the amount
100         */
101        public static Amount setPrecision(final Amount amount, int precision, RoundingMode roundingMode) {
102                if (amount == null) {
103                        return null;
104                }
105                return new Amount(amount.getValue().setScale(precision, roundingMode), amount.getCurrency());
106        }
107
108        /**
109         * Creates a copy of given {@link Amount} object.
110         * @param amount
111         * @return
112         */
113        public static Amount copy(final Amount amount) {
114                if (amount == null) {
115                        return null;
116                }
117                return new Amount(amount.getValue(), amount.getCurrency());
118        }
119}