001    /*
002     *  Copyright 2009-2013 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.money;
017    
018    import java.io.InvalidObjectException;
019    import java.io.ObjectInputStream;
020    import java.io.Serializable;
021    import java.math.BigDecimal;
022    import java.math.RoundingMode;
023    import java.util.Arrays;
024    import java.util.Iterator;
025    
026    import org.joda.convert.FromString;
027    import org.joda.convert.ToString;
028    
029    /**
030     * An amount of money with the standard decimal places defined by the currency.
031     * <p>
032     * This class represents a quantity of money, stored as a {@code BigDecimal} amount
033     * in a single {@link CurrencyUnit currency}.
034     * <p>
035     * Every currency has a certain standard number of decimal places.
036     * This is typically 2 (Euro, British Pound, US Dollar) but might be
037     * 0 (Japanese Yen), 1 (Vietnamese Dong) or 3 (Bahrain Dinar).
038     * The {@code Money} class is fixed to this number of decimal places.
039     * <p>
040     * For example, US dollars has a standard number of decimal places of 2.
041     * The major units are dollars. The minor units are cents, 100 to the dollar.
042     * This class does not allow calculations on fractions of a cent.
043     * <p>
044     * This class is immutable and thread-safe.
045     */
046    public final class Money implements BigMoneyProvider, Comparable<BigMoneyProvider>, Serializable {
047    
048        /**
049         * The serialisation version.
050         */
051        private static final long serialVersionUID = 1L;
052    
053        /**
054         * The money, not null.
055         */
056        private final BigMoney money;
057    
058        //-----------------------------------------------------------------------
059        /**
060         * Obtains an instance of {@code Money} from a {@code BigDecimal}.
061         * <p>
062         * This allows you to create an instance with a specific currency and amount.
063         * No rounding is performed on the amount, so it must have a scale compatible
064         * with the currency.
065         *
066         * @param currency  the currency, not null
067         * @param amount  the amount of money, not null
068         * @return the new instance, never null
069         * @throws ArithmeticException if the scale exceeds the currency scale
070         */
071        public static Money of(CurrencyUnit currency, BigDecimal amount) {
072            MoneyUtils.checkNotNull(currency, "Currency must not be null");
073            if (amount.scale() > currency.getDecimalPlaces()) {
074                throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency);
075            }
076            return Money.of(currency, amount, RoundingMode.UNNECESSARY);
077        }
078    
079        /**
080         * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary.
081         * <p>
082         * This allows you to create an instance with a specific currency and amount.
083         * If the amount has a scale in excess of the scale of the currency then the excess
084         * fractional digits are rounded using the rounding mode.
085         *
086         * @param currency  the currency, not null
087         * @param amount  the amount of money, not null
088         * @param roundingMode  the rounding mode to use, not null
089         * @return the new instance, never null
090         * @throws ArithmeticException if the rounding fails
091         */
092        public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) {
093            MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null");
094            MoneyUtils.checkNotNull(amount, "Amount must not be null");
095            MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null");
096            amount = amount.setScale(currency.getDecimalPlaces(), roundingMode);
097            return new Money(BigMoney.of(currency, amount));
098        }
099    
100        //-----------------------------------------------------------------------
101        /**
102         * Obtains an instance of {@code Money} from a {@code double} using a
103         * well-defined conversion.
104         * <p>
105         * This allows you to create an instance with a specific currency and amount.
106         * No rounding is performed on the amount, so it must have a scale compatible
107         * with the currency.
108         * <p>
109         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
110         * the most expected answer for most programming scenarios.
111         * Any {@code double} literal in code will be converted to
112         * exactly the same BigDecimal with the same scale.
113         * For example, the literal '1.45d' will be converted to '1.45'.
114         *
115         * @param currency  the currency, not null
116         * @param amount  the amount of money, not null
117         * @return the new instance, never null
118         * @throws ArithmeticException if the scale exceeds the currency scale
119         */
120        public static Money of(CurrencyUnit currency, double amount) {
121            return Money.of(currency, BigDecimal.valueOf(amount));
122        }
123    
124        /**
125         * Obtains an instance of {@code Money} from a {@code double} using a
126         * well-defined conversion, rounding as necessary.
127         * <p>
128         * This allows you to create an instance with a specific currency and amount.
129         * If the amount has a scale in excess of the scale of the currency then the excess
130         * fractional digits are rounded using the rounding mode.
131         * <p>
132         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
133         * the most expected answer for most programming scenarios.
134         * Any {@code double} literal in code will be converted to
135         * exactly the same BigDecimal with the same scale.
136         * For example, the literal '1.45d' will be converted to '1.45'.
137         *
138         * @param currency  the currency, not null
139         * @param amount  the amount of money, not null
140         * @param roundingMode  the rounding mode to use, not null
141         * @return the new instance, never null
142         * @throws ArithmeticException if the rounding fails
143         */
144        public static Money of(CurrencyUnit currency, double amount, RoundingMode roundingMode) {
145            return Money.of(currency, BigDecimal.valueOf(amount), roundingMode);
146        }
147    
148        //-----------------------------------------------------------------------
149        /**
150         * Obtains an instance of {@code Money} from an amount in major units.
151         * <p>
152         * This allows you to create an instance with a specific currency and amount.
153         * The amount is a whole number only. Thus you can initialise the value
154         * 'USD 20', but not the value 'USD 20.32'.
155         * For example, {@code ofMajor(USD, 25)} creates the instance {@code USD 25.00}.
156         *
157         * @param currency  the currency, not null
158         * @param amountMajor  the amount of money in the major division of the currency
159         * @return the new instance, never null
160         */
161        public static Money ofMajor(CurrencyUnit currency, long amountMajor) {
162            return Money.of(currency, BigDecimal.valueOf(amountMajor), RoundingMode.UNNECESSARY);
163        }
164    
165        /**
166         * Obtains an instance of {@code Money} from an amount in minor units.
167         * <p>
168         * This allows you to create an instance with a specific currency and amount
169         * expressed in terms of the minor unit.
170         * For example, if constructing US Dollars, the input to this method represents cents.
171         * Note that when a currency has zero decimal places, the major and minor units are the same.
172         * For example, {@code ofMajor(USD, 2595)} creates the instance {@code USD 25.95}.
173         *
174         * @param currency  the currency, not null
175         * @param amountMinor  the amount of money in the minor division of the currency
176         * @return the new instance, never null
177         */
178        public static Money ofMinor(CurrencyUnit currency, long amountMinor) {
179            return new Money(BigMoney.ofMinor(currency, amountMinor));
180        }
181    
182        //-----------------------------------------------------------------------
183        /**
184         * Obtains an instance of {@code Money} representing zero.
185         * <p>
186         * For example, {@code zero(USD)} creates the instance {@code USD 0.00}.
187         *
188         * @param currency  the currency, not null
189         * @return the instance representing zero, never null
190         */
191        public static Money zero(CurrencyUnit currency) {
192            MoneyUtils.checkNotNull(currency, "Currency must not be null");
193            BigDecimal bd = BigDecimal.valueOf(0, currency.getDecimalPlaces());
194            return new Money(BigMoney.of(currency, bd));
195        }
196    
197        //-----------------------------------------------------------------------
198        /**
199         * Obtains an instance of {@code Money} from a provider.
200         * <p>
201         * This allows you to create an instance from any class that implements the
202         * provider, such as {@code BigMoney}.
203         * No rounding is performed on the amount, so it must have a scale compatible
204         * with the currency.
205         *
206         * @param moneyProvider  the money to convert, not null
207         * @return the new instance, never null
208         * @throws ArithmeticException if the scale exceeds the currency scale
209         */
210        public static Money of(BigMoneyProvider moneyProvider) {
211            return Money.of(moneyProvider, RoundingMode.UNNECESSARY);
212        }
213    
214        /**
215         * Obtains an instance of {@code Money} from a provider, rounding as necessary.
216         * <p>
217         * This allows you to create an instance from any class that implements the
218         * provider, such as {@code BigMoney}.
219         * The rounding mode is used to adjust the scale to the scale of the currency.
220         *
221         * @param moneyProvider  the money to convert, not null
222         * @param roundingMode  the rounding mode to use, not null
223         * @return the new instance, never null
224         * @throws ArithmeticException if the rounding fails
225         */
226        public static Money of(BigMoneyProvider moneyProvider, RoundingMode roundingMode) {
227            MoneyUtils.checkNotNull(moneyProvider, "BigMoneyProvider must not be null");
228            MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null");
229            return new Money(BigMoney.of(moneyProvider).withCurrencyScale(roundingMode));
230        }
231    
232        //-----------------------------------------------------------------------
233        /**
234         * Obtains an instance of {@code Money} as the total value of an array.
235         * <p>
236         * The array must contain at least one monetary value.
237         * Subsequent amounts are added as though using {@link #plus(Money)}.
238         * All amounts must be in the same currency.
239         * 
240         * @param monies  the monetary values to total, not empty, no null elements, not null
241         * @return the total, never null
242         * @throws IllegalArgumentException if the array is empty
243         * @throws CurrencyMismatchException if the currencies differ
244         */
245        public static Money total(Money... monies) {
246            MoneyUtils.checkNotNull(monies, "Money array must not be null");
247            if (monies.length == 0) {
248                throw new IllegalArgumentException("Money array must not be empty");
249            }
250            Money total = monies[0];
251            MoneyUtils.checkNotNull(total, "Money arary must not contain null entries");
252            for (int i = 1; i < monies.length; i++) {
253                total = total.plus(monies[i]);
254            }
255            return total;
256        }
257    
258        /**
259         * Obtains an instance of {@code Money} as the total value of a collection.
260         * <p>
261         * The iterable must provide at least one monetary value.
262         * Subsequent amounts are added as though using {@link #plus(Money)}.
263         * All amounts must be in the same currency.
264         * 
265         * @param monies  the monetary values to total, not empty, no null elements, not null
266         * @return the total, never null
267         * @throws IllegalArgumentException if the iterable is empty
268         * @throws CurrencyMismatchException if the currencies differ
269         */
270        public static Money total(Iterable<Money> monies) {
271            MoneyUtils.checkNotNull(monies, "Money iterator must not be null");
272            Iterator<Money> it = monies.iterator();
273            if (it.hasNext() == false) {
274                throw new IllegalArgumentException("Money iterator must not be empty");
275            }
276            Money total = it.next();
277            MoneyUtils.checkNotNull(total, "Money iterator must not contain null entries");
278            while (it.hasNext()) {
279                total = total.plus(it.next());
280            }
281            return total;
282        }
283    
284        /**
285         * Obtains an instance of {@code Money} as the total value of
286         * a possibly empty array.
287         * <p>
288         * The amounts are added as though using {@link #plus(Money)} starting
289         * from zero in the specified currency.
290         * All amounts must be in the same currency.
291         * 
292         * @param currency  the currency to total in, not null
293         * @param monies  the monetary values to total, no null elements, not null
294         * @return the total, never null
295         * @throws CurrencyMismatchException if the currencies differ
296         */
297        public static Money total(CurrencyUnit currency, Money... monies) {
298            return Money.zero(currency).plus(Arrays.asList(monies));
299        }
300    
301        /**
302         * Obtains an instance of {@code Money} as the total value of
303         * a possibly empty collection.
304         * <p>
305         * The amounts are added as though using {@link #plus(Money)} starting
306         * from zero in the specified currency.
307         * All amounts must be in the same currency.
308         * 
309         * @param currency  the currency to total in, not null
310         * @param monies  the monetary values to total, no null elements, not null
311         * @return the total, never null
312         * @throws CurrencyMismatchException if the currencies differ
313         */
314        public static Money total(CurrencyUnit currency, Iterable<Money> monies) {
315            return Money.zero(currency).plus(monies);
316        }
317    
318        //-----------------------------------------------------------------------
319        /**
320         * Parses an instance of {@code Money} from a string.
321         * <p>
322         * The string format is '<currencyCode> <amount>'.
323         * The currency code must be a valid three letter currency.
324         * The amount must match the regular expression {@code [+-]?[0-9]*[.]?[0-9]*}.
325         * This matches the output from {@link #toString()}.
326         * <p>
327         * For example, {@code of("USD 25")} creates the instance {@code USD 25.00}
328         * while {@code of("USD 25.95")} creates the instance {@code USD 25.95}.
329         *
330         * @param moneyStr  the money string to parse, not null
331         * @return the parsed instance, never null
332         * @throws IllegalArgumentException if the string is malformed
333         * @throws ArithmeticException if the amount is too large
334         */
335        @FromString
336        public static Money parse(String moneyStr) {
337            return Money.of(BigMoney.parse(moneyStr));
338        }
339    
340        //-----------------------------------------------------------------------
341        /**
342         * Ensures that a {@code Money} is not {@code null}.
343         * <p>
344         * If the input money is not {@code null}, then it is returned, providing
345         * that the currency matches the specified currency.
346         * If the input money is {@code null}, then zero money in the currency is returned.
347         * 
348         * @param money  the monetary value to check, may be null
349         * @param currency  the currency to use, not null
350         * @return the input money or zero in the specified currency, never null
351         * @throws CurrencyMismatchException if the input money is non-null and the currencies differ
352         */
353        public static Money nonNull(Money money, CurrencyUnit currency) {
354            if (money == null) {
355                return zero(currency);
356            }
357            if (money.getCurrencyUnit().equals(currency) == false) {
358                MoneyUtils.checkNotNull(currency, "Currency must not be null");
359                throw new CurrencyMismatchException(money.getCurrencyUnit(), currency);
360            }
361            return money;
362        }
363    
364        //-----------------------------------------------------------------------
365        /**
366         * Constructor, creating a new monetary instance.
367         * 
368         * @param money  the underlying money, not null
369         */
370        Money(BigMoney money) {
371            assert money != null : "Joda-Money bug: BigMoney must not be null";
372            assert money.isCurrencyScale() : "Joda-Money bug: Only currency scale is valid for Money";
373            this.money = money;
374        }
375    
376        /**
377         * Block malicious data streams.
378         * 
379         * @param ois  the input stream, not null
380         * @throws InvalidObjectException
381         */
382        private void readObject(ObjectInputStream ois) throws InvalidObjectException {
383            throw new InvalidObjectException("Serialization delegate required");
384        }
385    
386        /**
387         * Uses a serialization delegate.
388         * 
389         * @return the replacing object, never null
390         */
391        private Object writeReplace() {
392            return new Ser(Ser.MONEY, this);
393        }
394    
395        //-----------------------------------------------------------------------
396        /**
397         * Returns a new {@code Money}, returning {@code this} if possible.
398         * <p>
399         * This instance is immutable and unaffected by this method.
400         * 
401         * @param newInstance  the new money to use, not null
402         * @return the new instance, never null
403         */
404        private Money with(BigMoney newInstance) {
405            if (money.equals(newInstance)) {
406                return this;
407            }
408            return new Money(newInstance);
409        }
410    
411        //-----------------------------------------------------------------------
412        /**
413         * Gets the currency.
414         * 
415         * @return the currency, never null
416         */
417        public CurrencyUnit getCurrencyUnit() {
418            return money.getCurrencyUnit();
419        }
420    
421        //-----------------------------------------------------------------------
422        /**
423         * Returns a copy of this monetary value with the specified currency.
424         * <p>
425         * The returned instance will have the specified currency and the amount
426         * from this instance. If the scale differs between the currencies such
427         * that rounding would be required, then an exception is thrown.
428         * <p>
429         * This instance is immutable and unaffected by this method.
430         * 
431         * @param currency  the currency to use, not null
432         * @return the new instance with the input currency set, never null
433         * @throws ArithmeticException if the scale of the new currency is less than
434         *  the scale of this currency
435         */
436        public Money withCurrencyUnit(CurrencyUnit currency) {
437            return withCurrencyUnit(currency, RoundingMode.UNNECESSARY);
438        }
439    
440        /**
441         * Returns a copy of this monetary value with the specified currency.
442         * <p>
443         * The returned instance will have the specified currency and the amount
444         * from this instance. If the number of decimal places differs between the
445         * currencies, then the amount may be rounded.
446         * <p>
447         * This instance is immutable and unaffected by this method.
448         * 
449         * @param currency  the currency to use, not null
450         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
451         * @return the new instance with the input currency set, never null
452         * @throws ArithmeticException if the rounding fails
453         */
454        public Money withCurrencyUnit(CurrencyUnit currency, RoundingMode roundingMode) {
455            return with(money.withCurrencyUnit(currency).withCurrencyScale(roundingMode));
456        }
457    
458        //-----------------------------------------------------------------------
459        /**
460         * Gets the scale of the {@code BigDecimal} amount.
461         * <p>
462         * The scale has the same meaning as in {@link BigDecimal}.
463         * Positive values represent the number of decimal places in use.
464         * For example, a scale of 2 means that the money will have two decimal places
465         * such as 'USD 43.25'.
466         * <p>
467         * For {@code Money}, the scale is fixed and always matches that of the currency.
468         * 
469         * @return the scale in use, typically 2 but could be 0, 1 and 3
470         */
471        public int getScale() {
472            return money.getScale();
473        }
474    
475        //-----------------------------------------------------------------------
476        /**
477         * Gets the amount.
478         * <p>
479         * This returns the value of the money as a {@code BigDecimal}.
480         * The scale will be the scale of this money.
481         * 
482         * @return the amount, never null
483         */
484        public BigDecimal getAmount() {
485            return money.getAmount();
486        }
487    
488        /**
489         * Gets the amount in major units as a {@code BigDecimal} with scale 0.
490         * <p>
491         * This returns the monetary amount in terms of the major units of the currency,
492         * truncating the amount if necessary.
493         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
494         * <p>
495         * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}.
496         * This is to allow further calculations to be performed on the result.
497         * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}.
498         * 
499         * @return the major units part of the amount, never null
500         */
501        public BigDecimal getAmountMajor() {
502            return money.getAmountMajor();
503        }
504    
505        /**
506         * Gets the amount in major units as a {@code long}.
507         * <p>
508         * This returns the monetary amount in terms of the major units of the currency,
509         * truncating the amount if necessary.
510         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
511         * 
512         * @return the major units part of the amount
513         * @throws ArithmeticException if the amount is too large for a {@code long}
514         */
515        public long getAmountMajorLong() {
516            return money.getAmountMajorLong();
517        }
518    
519        /**
520         * Gets the amount in major units as an {@code int}.
521         * <p>
522         * This returns the monetary amount in terms of the major units of the currency,
523         * truncating the amount if necessary.
524         * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1.
525         * 
526         * @return the major units part of the amount
527         * @throws ArithmeticException if the amount is too large for an {@code int}
528         */
529        public int getAmountMajorInt() {
530            return money.getAmountMajorInt();
531        }
532    
533        /**
534         * Gets the amount in minor units as a {@code BigDecimal} with scale 0.
535         * <p>
536         * This returns the monetary amount in terms of the minor units of the currency,
537         * truncating the amount if necessary.
538         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
539         * <p>
540         * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}.
541         * This is to allow further calculations to be performed on the result.
542         * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}.
543         * 
544         * @return the minor units part of the amount, never null
545         */
546        public BigDecimal getAmountMinor() {
547            return money.getAmountMinor();
548        }
549    
550        /**
551         * Gets the amount in minor units as a {@code long}.
552         * <p>
553         * This returns the monetary amount in terms of the minor units of the currency,
554         * truncating the amount if necessary.
555         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
556         * 
557         * @return the minor units part of the amount
558         * @throws ArithmeticException if the amount is too large for a {@code long}
559         */
560        public long getAmountMinorLong() {
561            return money.getAmountMinorLong();
562        }
563    
564        /**
565         * Gets the amount in minor units as an {@code int}.
566         * <p>
567         * This returns the monetary amount in terms of the minor units of the currency,
568         * truncating the amount if necessary.
569         * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345.
570         * 
571         * @return the minor units part of the amount
572         * @throws ArithmeticException if the amount is too large for an {@code int}
573         */
574        public int getAmountMinorInt() {
575            return money.getAmountMinorInt();
576        }
577    
578        /**
579         * Gets the minor part of the amount.
580         * <p>
581         * This return the minor unit part of the monetary amount.
582         * This is defined as the amount in minor units excluding major units.
583         * <p>
584         * For example, EUR has a scale of 2, so the minor part is always between 0 and 99
585         * for positive amounts, and 0 and -99 for negative amounts.
586         * Thus 'EUR 2.35' will return 35, and 'EUR -1.34' will return -34.
587         * 
588         * @return the minor part of the amount, negative if the amount is negative
589         */
590        public int getMinorPart() {
591            return money.getMinorPart();
592        }
593    
594        //-----------------------------------------------------------------------
595        /**
596         * Checks if the amount is zero.
597         * 
598         * @return true if the amount is zero
599         */
600        public boolean isZero() {
601            return money.isZero();
602        }
603    
604        /**
605         * Checks if the amount is greater than zero.
606         * 
607         * @return true if the amount is greater than zero
608         */
609        public boolean isPositive() {
610            return money.isPositive();
611        }
612    
613        /**
614         * Checks if the amount is zero or greater.
615         * 
616         * @return true if the amount is zero or greater
617         */
618        public boolean isPositiveOrZero() {
619            return money.isPositiveOrZero();
620        }
621    
622        /**
623         * Checks if the amount is less than zero.
624         * 
625         * @return true if the amount is less than zero
626         */
627        public boolean isNegative() {
628            return money.isNegative();
629        }
630    
631        /**
632         * Checks if the amount is zero or less.
633         * 
634         * @return true if the amount is zero or less
635         */
636        public boolean isNegativeOrZero() {
637            return money.isNegativeOrZero();
638        }
639    
640        //-----------------------------------------------------------------------
641        /**
642         * Returns a copy of this monetary value with the specified amount.
643         * <p>
644         * The returned instance will have this currency and the new amount.
645         * No rounding is performed on the amount to be added, so it must have a
646         * scale compatible with the currency.
647         * <p>
648         * This instance is immutable and unaffected by this method.
649         * 
650         * @param amount  the monetary amount to set in the returned instance, not null
651         * @return the new instance with the input amount set, never null
652         * @throws ArithmeticException if the scale of the amount is too large
653         */
654        public Money withAmount(BigDecimal amount) {
655            return withAmount(amount, RoundingMode.UNNECESSARY);
656        }
657    
658        /**
659         * Returns a copy of this monetary value with the specified amount.
660         * <p>
661         * The returned instance will have this currency and the new amount.
662         * If the scale of the {@code BigDecimal} needs to be adjusted, then
663         * it will be rounded using the specified mode.
664         * <p>
665         * This instance is immutable and unaffected by this method.
666         * 
667         * @param amount  the monetary amount to set in the returned instance, not null
668         * @param roundingMode  the rounding mode to adjust the scale, not null
669         * @return the new instance with the input amount set, never null
670         */
671        public Money withAmount(BigDecimal amount, RoundingMode roundingMode) {
672            return with(money.withAmount(amount).withCurrencyScale(roundingMode));
673        }
674    
675        /**
676         * Returns a copy of this monetary value with the specified amount using a well-defined
677         * conversion from a {@code double}.
678         * <p>
679         * The returned instance will have this currency and the new amount.
680         * No rounding is performed on the amount to be added, so it must have a
681         * scale compatible with the currency.
682         * <p>
683         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
684         * the most expected answer for most programming scenarios.
685         * Any {@code double} literal in code will be converted to
686         * exactly the same BigDecimal with the same scale.
687         * For example, the literal '1.45d' will be converted to '1.45'.
688         * <p>
689         * This instance is immutable and unaffected by this method.
690         * 
691         * @param amount  the monetary amount to set in the returned instance, not null
692         * @return the new instance with the input amount set, never null
693         * @throws ArithmeticException if the scale of the amount is too large
694         */
695        public Money withAmount(double amount) {
696            return withAmount(amount, RoundingMode.UNNECESSARY);
697        }
698    
699        /**
700         * Returns a copy of this monetary value with the specified amount using a well-defined
701         * conversion from a {@code double}.
702         * <p>
703         * The returned instance will have this currency and the new amount.
704         * If the scale of the {@code BigDecimal} needs to be adjusted, then
705         * it will be rounded using the specified mode.
706         * <p>
707         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
708         * the most expected answer for most programming scenarios.
709         * Any {@code double} literal in code will be converted to
710         * exactly the same BigDecimal with the same scale.
711         * For example, the literal '1.45d' will be converted to '1.45'.
712         * <p>
713         * This instance is immutable and unaffected by this method.
714         * 
715         * @param amount  the monetary amount to set in the returned instance, not null
716         * @param roundingMode  the rounding mode to adjust the scale, not null
717         * @return the new instance with the input amount set, never null
718         */
719        public Money withAmount(double amount, RoundingMode roundingMode) {
720            return with(money.withAmount(amount).withCurrencyScale(roundingMode));
721        }
722    
723        //-----------------------------------------------------------------------
724        /**
725         * Returns a copy of this monetary value with a collection of monetary amounts added.
726         * <p>
727         * This adds the specified amounts to this monetary amount, returning a new object.
728         * The amounts must be in the same currency.
729         * <p>
730         * This instance is immutable and unaffected by this method.
731         * 
732         * @param moniesToAdd  the monetary values to add, no null elements, not null
733         * @return the new instance with the input amounts added, never null
734         * @throws CurrencyMismatchException if the currencies differ
735         */
736        public Money plus(Iterable<Money> moniesToAdd) {
737            return with(money.plus(moniesToAdd));
738        }
739    
740        //-----------------------------------------------------------------------
741        /**
742         * Returns a copy of this monetary value with the amount added.
743         * <p>
744         * This adds the specified amount to this monetary amount, returning a new object.
745         * The amount added must be in the same currency.
746         * <p>
747         * The addition has no rounding issues and is always accurate.
748         * For example,'USD 25.95' plus 'USD 3.02' will 'USD 28.97'.
749         * <p>
750         * This instance is immutable and unaffected by this method.
751         * 
752         * @param moneyToAdd  the monetary value to add, not null
753         * @return the new instance with the input amount added, never null
754         * @throws CurrencyMismatchException if the currencies differ
755         */
756        public Money plus(Money moneyToAdd) {
757            return with(money.plus(moneyToAdd));
758        }
759    
760        /**
761         * Returns a copy of this monetary value with the amount added.
762         * <p>
763         * This adds the specified amount to this monetary amount, returning a new object.
764         * No rounding is performed on the amount to be added, so it must have a
765         * scale compatible with the currency.
766         * <p>
767         * This instance is immutable and unaffected by this method.
768         * 
769         * @param amountToAdd  the monetary value to add, not null
770         * @return the new instance with the input amount added, never null
771         * @throws ArithmeticException if the scale of the amount is too large
772         */
773        public Money plus(BigDecimal amountToAdd) {
774            return plus(amountToAdd, RoundingMode.UNNECESSARY);
775        }
776    
777        /**
778         * Returns a copy of this monetary value with the amount added.
779         * <p>
780         * This adds the specified amount to this monetary amount, returning a new object.
781         * If the amount to add exceeds the scale of the currency, then the
782         * rounding mode will be used to adjust the result.
783         * <p>
784         * This instance is immutable and unaffected by this method.
785         * 
786         * @param amountToAdd  the monetary value to add, not null
787         * @return the new instance with the input amount added, never null
788         */
789        public Money plus(BigDecimal amountToAdd, RoundingMode roundingMode) {
790            return with(money.plusRetainScale(amountToAdd, roundingMode));
791        }
792    
793        /**
794         * Returns a copy of this monetary value with the amount added.
795         * <p>
796         * This adds the specified amount to this monetary amount, returning a new object.
797         * No rounding is performed on the amount to be added, so it must have a
798         * scale compatible with the currency.
799         * <p>
800         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
801         * the most expected answer for most programming scenarios.
802         * Any {@code double} literal in code will be converted to
803         * exactly the same BigDecimal with the same scale.
804         * For example, the literal '1.45d' will be converted to '1.45'.
805         * <p>
806         * This instance is immutable and unaffected by this method.
807         * 
808         * @param amountToAdd  the monetary value to add, not null
809         * @return the new instance with the input amount added, never null
810         * @throws ArithmeticException if the scale of the amount is too large
811         */
812        public Money plus(double amountToAdd) {
813            return plus(amountToAdd, RoundingMode.UNNECESSARY);
814        }
815    
816        /**
817         * Returns a copy of this monetary value with the amount added.
818         * <p>
819         * This adds the specified amount to this monetary amount, returning a new object.
820         * If the amount to add exceeds the scale of the currency, then the
821         * rounding mode will be used to adjust the result.
822         * <p>
823         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
824         * the most expected answer for most programming scenarios.
825         * Any {@code double} literal in code will be converted to
826         * exactly the same BigDecimal with the same scale.
827         * For example, the literal '1.45d' will be converted to '1.45'.
828         * <p>
829         * This instance is immutable and unaffected by this method.
830         * 
831         * @param amountToAdd  the monetary value to add, not null
832         * @return the new instance with the input amount added, never null
833         */
834        public Money plus(double amountToAdd, RoundingMode roundingMode) {
835            return with(money.plusRetainScale(amountToAdd, roundingMode));
836        }
837    
838        /**
839         * Returns a copy of this monetary value with the amount in major units added.
840         * <p>
841         * This adds an amount in major units, leaving the minor units untouched.
842         * For example, USD 23.45 plus 138 gives USD 161.45.
843         * <p>
844         * This instance is immutable and unaffected by this method.
845         * 
846         * @param amountToAdd  the monetary value to add, not null
847         * @return the new instance with the input amount added, never null
848         */
849        public Money plusMajor(long amountToAdd) {
850            return with(money.plusMajor(amountToAdd));
851        }
852    
853        /**
854         * Returns a copy of this monetary value with the amount in minor units added.
855         * <p>
856         * This adds an amount in minor units.
857         * For example, USD 23.45 plus 138 gives USD 24.83.
858         * <p>
859         * This instance is immutable and unaffected by this method.
860         * 
861         * @param amountToAdd  the monetary value to add, not null
862         * @return the new instance with the input amount added, never null
863         */
864        public Money plusMinor(long amountToAdd) {
865            return with(money.plusMinor(amountToAdd));
866        }
867    
868        //-----------------------------------------------------------------------
869        /**
870         * Returns a copy of this monetary value with a collection of monetary amounts subtracted.
871         * <p>
872         * This subtracts the specified amounts from this monetary amount, returning a new object.
873         * The amounts must be in the same currency.
874         * <p>
875         * This instance is immutable and unaffected by this method.
876         * 
877         * @param moniesToSubtract  the monetary values to subtract, no null elements, not null
878         * @return the new instance with the input amounts subtracted, never null
879         * @throws CurrencyMismatchException if the currencies differ
880         */
881        public Money minus(Iterable<Money> moniesToSubtract) {
882            return with(money.minus(moniesToSubtract));
883        }
884    
885        //-----------------------------------------------------------------------
886        /**
887         * Returns a copy of this monetary value with the amount subtracted.
888         * <p>
889         * This subtracts the specified amount from this monetary amount, returning a new object.
890         * The amount subtracted must be in the same currency.
891         * <p>
892         * The subtraction has no rounding issues and is always accurate.
893         * For example,'USD 25.95' minus 'USD 3.02' will 'USD 22.93'.
894         * <p>
895         * This instance is immutable and unaffected by this method.
896         * 
897         * @param moneyToSubtract  the monetary value to subtract, not null
898         * @return the new instance with the input amount subtracted, never null
899         * @throws CurrencyMismatchException if the currencies differ
900         */
901        public Money minus(Money moneyToSubtract) {
902            return with(money.minus(moneyToSubtract));
903        }
904    
905        /**
906         * Returns a copy of this monetary value with the amount subtracted.
907         * <p>
908         * This subtracts the specified amount from this monetary amount, returning a new object.
909         * No rounding is performed on the amount to be subtracted, so it must have a
910         * scale compatible with the currency.
911         * <p>
912         * This instance is immutable and unaffected by this method.
913         * 
914         * @param amountToSubtract  the monetary value to subtract, not null
915         * @return the new instance with the input amount subtracted, never null
916         * @throws ArithmeticException if the scale of the amount is too large
917         */
918        public Money minus(BigDecimal amountToSubtract) {
919            return minus(amountToSubtract, RoundingMode.UNNECESSARY);
920        }
921    
922        /**
923         * Returns a copy of this monetary value with the amount subtracted.
924         * <p>
925         * This subtracts the specified amount from this monetary amount, returning a new object.
926         * If the amount to subtract exceeds the scale of the currency, then the
927         * rounding mode will be used to adjust the result.
928         * <p>
929         * This instance is immutable and unaffected by this method.
930         * 
931         * @param amountToSubtract  the monetary value to subtract, not null
932         * @return the new instance with the input amount subtracted, never null
933         */
934        public Money minus(BigDecimal amountToSubtract, RoundingMode roundingMode) {
935            return with(money.minusRetainScale(amountToSubtract, roundingMode));
936        }
937    
938        /**
939         * Returns a copy of this monetary value with the amount subtracted.
940         * <p>
941         * This subtracts the specified amount from this monetary amount, returning a new object.
942         * No rounding is performed on the amount to be subtracted, so it must have a
943         * scale compatible with the currency.
944         * <p>
945         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
946         * the most expected answer for most programming scenarios.
947         * Any {@code double} literal in code will be converted to
948         * exactly the same BigDecimal with the same scale.
949         * For example, the literal '1.45d' will be converted to '1.45'.
950         * <p>
951         * This instance is immutable and unaffected by this method.
952         * 
953         * @param amountToSubtract  the monetary value to subtract, not null
954         * @return the new instance with the input amount subtracted, never null
955         * @throws ArithmeticException if the scale of the amount is too large
956         */
957        public Money minus(double amountToSubtract) {
958            return minus(amountToSubtract, RoundingMode.UNNECESSARY);
959        }
960    
961        /**
962         * Returns a copy of this monetary value with the amount subtracted.
963         * <p>
964         * This subtracts the specified amount from this monetary amount, returning a new object.
965         * If the amount to subtract exceeds the scale of the currency, then the
966         * rounding mode will be used to adjust the result.
967         * <p>
968         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
969         * the most expected answer for most programming scenarios.
970         * Any {@code double} literal in code will be converted to
971         * exactly the same BigDecimal with the same scale.
972         * For example, the literal '1.45d' will be converted to '1.45'.
973         * <p>
974         * This instance is immutable and unaffected by this method.
975         * 
976         * @param amountToSubtract  the monetary value to subtract, not null
977         * @return the new instance with the input amount subtracted, never null
978         */
979        public Money minus(double amountToSubtract, RoundingMode roundingMode) {
980            return with(money.minusRetainScale(amountToSubtract, roundingMode));
981        }
982    
983        /**
984         * Returns a copy of this monetary value with the amount in major units subtracted.
985         * <p>
986         * This subtracts an amount in major units, leaving the minor units untouched.
987         * For example, USD 23.45 minus 138 gives USD -114.55.
988         * <p>
989         * This instance is immutable and unaffected by this method.
990         * 
991         * @param amountToSubtract  the monetary value to subtract, not null
992         * @return the new instance with the input amount subtracted, never null
993         */
994        public Money minusMajor(long amountToSubtract) {
995            return with(money.minusMajor(amountToSubtract));
996        }
997    
998        /**
999         * Returns a copy of this monetary value with the amount in minor units subtracted.
1000         * <p>
1001         * This subtracts an amount in minor units.
1002         * For example, USD 23.45 minus 138 gives USD 22.07.
1003         * <p>
1004         * This instance is immutable and unaffected by this method.
1005         * 
1006         * @param amountToSubtract  the monetary value to subtract, not null
1007         * @return the new instance with the input amount subtracted, never null
1008         */
1009        public Money minusMinor(long amountToSubtract) {
1010            return with(money.minusMinor(amountToSubtract));
1011        }
1012    
1013        //-----------------------------------------------------------------------
1014        /**
1015         * Returns a copy of this monetary value multiplied by the specified value.
1016         * <p>
1017         * This takes this amount and multiplies it by the specified value, rounding
1018         * the result is rounded as specified.
1019         * <p>
1020         * This instance is immutable and unaffected by this method.
1021         * 
1022         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1023         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1024         * @return the new multiplied instance, never null
1025         * @throws ArithmeticException if the rounding fails
1026         */
1027        public Money multipliedBy(BigDecimal valueToMultiplyBy, RoundingMode roundingMode) {
1028            return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode));
1029        }
1030    
1031        /**
1032         * Returns a copy of this monetary value multiplied by the specified value.
1033         * <p>
1034         * This takes this amount and multiplies it by the specified value, rounding
1035         * the result is rounded as specified.
1036         * <p>
1037         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
1038         * the most expected answer for most programming scenarios.
1039         * Any {@code double} literal in code will be converted to
1040         * exactly the same BigDecimal with the same scale.
1041         * For example, the literal '1.45d' will be converted to '1.45'.
1042         * <p>
1043         * This instance is immutable and unaffected by this method.
1044         * 
1045         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1046         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1047         * @return the new multiplied instance, never null
1048         * @throws ArithmeticException if the rounding fails
1049         */
1050        public Money multipliedBy(double valueToMultiplyBy, RoundingMode roundingMode) {
1051            return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode));
1052        }
1053    
1054        /**
1055         * Returns a copy of this monetary value multiplied by the specified value.
1056         * <p>
1057         * This takes this amount and multiplies it by the specified value.
1058         * <p>
1059         * This instance is immutable and unaffected by this method.
1060         * 
1061         * @param valueToMultiplyBy  the scalar value to multiply by, not null
1062         * @return the new multiplied instance, never null
1063         */
1064        public Money multipliedBy(long valueToMultiplyBy) {
1065            return with(money.multipliedBy(valueToMultiplyBy));
1066        }
1067    
1068        //-----------------------------------------------------------------------
1069        /**
1070         * Returns a copy of this monetary value divided by the specified value.
1071         * <p>
1072         * This takes this amount and divides it by the specified value, rounding
1073         * the result is rounded as specified.
1074         * <p>
1075         * This instance is immutable and unaffected by this method.
1076         * 
1077         * @param valueToDivideBy  the scalar value to divide by, not null
1078         * @param roundingMode  the rounding mode to use, not null
1079         * @return the new divided instance, never null
1080         * @throws ArithmeticException if dividing by zero
1081         * @throws ArithmeticException if the rounding fails
1082         */
1083        public Money dividedBy(BigDecimal valueToDivideBy, RoundingMode roundingMode) {
1084            return with(money.dividedBy(valueToDivideBy, roundingMode));
1085        }
1086    
1087        /**
1088         * Returns a copy of this monetary value divided by the specified value.
1089         * <p>
1090         * This takes this amount and divides it by the specified value, rounding
1091         * the result is rounded as specified.
1092         * <p>
1093         * The amount is converted via {@link BigDecimal#valueOf(double)} which yields
1094         * the most expected answer for most programming scenarios.
1095         * Any {@code double} literal in code will be converted to
1096         * exactly the same BigDecimal with the same scale.
1097         * For example, the literal '1.45d' will be converted to '1.45'.
1098         * <p>
1099         * This instance is immutable and unaffected by this method.
1100         * 
1101         * @param valueToDivideBy  the scalar value to divide by, not null
1102         * @param roundingMode  the rounding mode to use, not null
1103         * @return the new divided instance, never null
1104         * @throws ArithmeticException if dividing by zero
1105         * @throws ArithmeticException if the rounding fails
1106         */
1107        public Money dividedBy(double valueToDivideBy, RoundingMode roundingMode) {
1108            return with(money.dividedBy(valueToDivideBy, roundingMode));
1109        }
1110    
1111        /**
1112         * Returns a copy of this monetary value divided by the specified value.
1113         * <p>
1114         * This takes this amount and divides it by the specified value, rounding
1115         * the result is rounded as specified.
1116         * <p>
1117         * This instance is immutable and unaffected by this method.
1118         * 
1119         * @param valueToDivideBy  the scalar value to divide by, not null
1120         * @return the new divided instance, never null
1121         * @throws ArithmeticException if dividing by zero
1122         * @throws ArithmeticException if the rounding fails
1123         */
1124        public Money dividedBy(long valueToDivideBy, RoundingMode roundingMode) {
1125            return with(money.dividedBy(valueToDivideBy, roundingMode));
1126        }
1127    
1128        //-----------------------------------------------------------------------
1129        /**
1130         * Returns a copy of this monetary value with the amount negated.
1131         * <p>
1132         * This instance is immutable and unaffected by this method.
1133         * 
1134         * @return the new instance with the amount negated, never null
1135         */
1136        public Money negated() {
1137            return with(money.negated());
1138        }
1139    
1140        /**
1141         * Returns a copy of this monetary value with a positive amount.
1142         * <p>
1143         * This instance is immutable and unaffected by this method.
1144         * 
1145         * @return the new instance with the amount converted to be positive, never null
1146         */
1147        public Money abs() {
1148            return (isNegative() ? negated() : this);
1149        }
1150    
1151        //-----------------------------------------------------------------------
1152        /**
1153         * Returns a copy of this monetary value rounded to the specified scale without
1154         * changing the current scale.
1155         * <p>
1156         * Scale has the same meaning as in {@link BigDecimal}.
1157         * A scale of 2 means round to 2 decimal places.
1158         * <ul>
1159         * <li>Rounding 'EUR 45.23' to a scale of -1 returns 40.00 or 50.00 depending on the rounding mode.
1160         * <li>Rounding 'EUR 45.23' to a scale of 0 returns 45.00 or 46.00 depending on the rounding mode.
1161         * <li>Rounding 'EUR 45.23' to a scale of 1 returns 45.20 or 45.30 depending on the rounding mode.
1162         * <li>Rounding 'EUR 45.23' to a scale of 2 has no effect (it already has that scale).
1163         * <li>Rounding 'EUR 45.23' to a scale of 3 has no effect (the scale is not increased).
1164         * </ul>
1165         * <p>
1166         * This instance is immutable and unaffected by this method.
1167         * 
1168         * @param scale  the new scale
1169         * @param roundingMode  the rounding mode to use, not null
1170         * @return the new instance with the amount converted to be positive, never null
1171         * @throws ArithmeticException if the rounding fails
1172         */
1173        public Money rounded(int scale, RoundingMode roundingMode) {
1174            return with(money.rounded(scale, roundingMode));
1175        }
1176    
1177        //-----------------------------------------------------------------------
1178        /**
1179         * Returns a copy of this monetary value converted into another currency
1180         * using the specified conversion rate, with a rounding mode used to adjust
1181         * the decimal places in the result.
1182         * <p>
1183         * This instance is immutable and unaffected by this method.
1184         * 
1185         * @param currency  the new currency, not null
1186         * @param conversionMultipler  the conversion factor between the currencies, not null
1187         * @param roundingMode  the rounding mode to use to bring the decimal places back in line, not null
1188         * @return the new multiplied instance, never null
1189         * @throws IllegalArgumentException if the currency is the same as this currency
1190         * @throws IllegalArgumentException if the conversion multiplier is negative
1191         * @throws ArithmeticException if the rounding fails
1192         */
1193        public Money convertedTo(CurrencyUnit currency, BigDecimal conversionMultipler, RoundingMode roundingMode) {
1194            return with(money.convertedTo(currency, conversionMultipler).withCurrencyScale(roundingMode));
1195        }
1196    
1197        //-----------------------------------------------------------------------
1198        /**
1199         * Implements the {@code BigMoneyProvider} interface, returning a
1200         * {@code BigMoney} instance with the same currency, amount and scale.
1201         * 
1202         * @return the money instance, never null
1203         */
1204        public BigMoney toBigMoney() {
1205            return money;
1206        }
1207    
1208        //-----------------------------------------------------------------------
1209        /**
1210         * Checks if this instance and the specified instance have the same currency.
1211         * 
1212         * @param other  the money to check, not null
1213         * @return true if they have the same currency
1214         */
1215        public boolean isSameCurrency(BigMoneyProvider other) {
1216            return money.isSameCurrency(other);
1217        }
1218    
1219        //-----------------------------------------------------------------------
1220        /**
1221         * Compares this monetary value to another.
1222         * <p>
1223         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1224         * Scale is ignored in the comparison.
1225         * The compared values must be in the same currency.
1226         * 
1227         * @param other  the other monetary value, not null
1228         * @return -1 if this is less than , 0 if equal, 1 if greater than
1229         * @throws CurrencyMismatchException if the currencies differ
1230         */
1231        public int compareTo(BigMoneyProvider other) {
1232            return money.compareTo(other);
1233        }
1234    
1235        /**
1236         * Checks if this monetary value is equal to another.
1237         * <p>
1238         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1239         * Scale is ignored, so 'USD 30.00' and 'USD 30' are equal.
1240         * The compared values must be in the same currency.
1241         * 
1242         * @param other  the other monetary value, not null
1243         * @return true is this is greater than the specified monetary value
1244         * @throws CurrencyMismatchException if the currencies differ
1245         * @see #equals(Object)
1246         */
1247        public boolean isEqual(BigMoneyProvider other) {
1248            return money.isEqual(other);
1249        }
1250    
1251        /**
1252         * Checks if this monetary value is greater than another.
1253         * <p>
1254         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1255         * Scale is ignored in the comparison.
1256         * The compared values must be in the same currency.
1257         * 
1258         * @param other  the other monetary value, not null
1259         * @return true is this is greater than the specified monetary value
1260         * @throws CurrencyMismatchException if the currencies differ
1261         */
1262        public boolean isGreaterThan(BigMoneyProvider other) {
1263            return money.isGreaterThan(other);
1264        }
1265    
1266        /**
1267         * Checks if this monetary value is less than another.
1268         * <p>
1269         * This allows {@code Money} to be compared to any {@code BigMoneyProvider}.
1270         * Scale is ignored in the comparison.
1271         * The compared values must be in the same currency.
1272         * 
1273         * @param other  the other monetary value, not null
1274         * @return true is this is less than the specified monetary value
1275         * @throws CurrencyMismatchException if the currencies differ
1276         */
1277        public boolean isLessThan(BigMoneyProvider other) {
1278            return money.isLessThan(other);
1279        }
1280    
1281        //-----------------------------------------------------------------------
1282        /**
1283         * Checks if this monetary value equals another.
1284         * <p>
1285         * The comparison takes into account the scale.
1286         * The compared values must be in the same currency.
1287         * 
1288         * @return true if this instance equals the other instance
1289         */
1290        @Override
1291        public boolean equals(Object other) {
1292            if (this == other) {
1293                return true;
1294            }
1295            if (other instanceof Money) {
1296                Money otherMoney = (Money) other;
1297                return money.equals(otherMoney.money);
1298            }
1299            return false;
1300        }
1301    
1302        /**
1303         * Returns a hash code for this monetary value.
1304         * 
1305         * @return a suitable hash code
1306         */
1307        @Override
1308        public int hashCode() {
1309            return money.hashCode() + 3;
1310        }
1311    
1312        //-----------------------------------------------------------------------
1313        /**
1314         * Gets the monetary value as a string.
1315         * <p>
1316         * The format is the 3 letter ISO currency code, followed by a space,
1317         * followed by the amount as per {@link BigDecimal#toPlainString()}.
1318         * 
1319         * @return the string representation of this monetary value, never null
1320         */
1321        @Override
1322        @ToString
1323        public String toString() {
1324            return money.toString();
1325        }
1326    
1327    }