View Javadoc
1   /*
2    * Oceanus: Java Utilities
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.oceanus.decimal;
18  
19  import java.util.Currency;
20  
21  /**
22   * Represents a Price object.
23   */
24  public class OceanusPrice
25          extends OceanusMoney {
26      /**
27       * Additional number of decimals for Price.
28       */
29      static final int XTRA_DECIMALS = 2;
30  
31      /**
32       * Constructor for price of value zero in the default currency.
33       */
34      public OceanusPrice() {
35          this(DEFAULT_CURRENCY);
36      }
37  
38      /**
39       * Constructor for money of value zero in specified currency.
40       *
41       * @param pCurrency the currency
42       */
43      public OceanusPrice(final Currency pCurrency) {
44          super(pCurrency);
45          recordScale(pCurrency.getDefaultFractionDigits()
46                  + XTRA_DECIMALS);
47      }
48  
49      /**
50       * Construct a new Price by copying another price.
51       *
52       * @param pPrice the Price to copy
53       */
54      public OceanusPrice(final OceanusPrice pPrice) {
55          super(pPrice.getCurrency());
56          setValue(pPrice.unscaledValue(), pPrice.scale());
57      }
58  
59      /**
60       * Constructor for price from a decimal string.
61       *
62       * @param pSource The source decimal string
63       * @throws IllegalArgumentException on invalidly formatted argument
64       */
65      public OceanusPrice(final String pSource) {
66          /* Use default constructor */
67          this();
68  
69          /* Parse the string and correct the scale */
70          OceanusDecimalParser.parseDecimalValue(pSource, this);
71          adjustToScale(getCurrency().getDefaultFractionDigits()
72                  + XTRA_DECIMALS);
73      }
74  
75      /**
76       * Constructor for price from a decimal string.
77       *
78       * @param pSource   The source decimal string
79       * @param pCurrency the currency
80       * @throws IllegalArgumentException on invalidly formatted argument
81       */
82      public OceanusPrice(final String pSource,
83                          final Currency pCurrency) {
84          /* Use default constructor */
85          this(pCurrency);
86  
87          /* Parse the string and correct the scale */
88          OceanusDecimalParser.parseDecimalValue(pSource, this);
89          adjustToScale(getCurrency().getDefaultFractionDigits()
90                  + XTRA_DECIMALS);
91      }
92  
93      /**
94       * Create the price from a byte array.
95       *
96       * @param pBuffer the buffer
97       */
98      public OceanusPrice(final byte[] pBuffer) {
99          super(pBuffer);
100     }
101 
102     /**
103      * Factory method for generating whole monetary units for a currency (e.g. £)
104      *
105      * @param pUnits    the number of whole monetary units
106      * @param pCurrency the currency
107      * @return the allocated price
108      */
109     public static OceanusPrice getWholeUnits(final long pUnits,
110                                              final Currency pCurrency) {
111         /* Allocate the money */
112         final OceanusPrice myResult = new OceanusPrice(pCurrency);
113         final int myScale = myResult.scale();
114         myResult.setValue(adjustDecimals(pUnits, myScale), myScale);
115         return myResult;
116     }
117 
118     /**
119      * Factory method for generating whole monetary units (e.g. £)
120      *
121      * @param pUnits the number of whole monetary units
122      * @return the allocated price
123      */
124     public static OceanusPrice getWholeUnits(final long pUnits) {
125         /* Allocate the price */
126         final OceanusPrice myResult = new OceanusPrice();
127         final int myScale = myResult.scale();
128         myResult.setValue(adjustDecimals(pUnits, myScale), myScale);
129         return myResult;
130     }
131 
132     @Override
133     public OceanusPrice changeCurrency(final Currency pCurrency) {
134         /* Convert currency with an exchange rate of one */
135         return convertCurrency(pCurrency, OceanusRatio.ONE);
136     }
137 
138     @Override
139     public OceanusPrice convertCurrency(final Currency pCurrency,
140                                         final OceanusRatio pRate) {
141         /* If this is the same currency then no conversion */
142         if (getCurrency().equals(pCurrency)) {
143             return new OceanusPrice(this);
144         }
145 
146         /* Create the new Price */
147         final OceanusPrice myResult = new OceanusPrice(pCurrency);
148         myResult.calculateProduct(this, pRate);
149         return myResult;
150     }
151 
152     /**
153      * Subtract a monetary price from the value.
154      *
155      * @param pValue The money to subtract from this one.
156      */
157     public void subtractPrice(final OceanusPrice pValue) {
158         /* Currency must be identical */
159         if (!getCurrency().equals(pValue.getCurrency())) {
160             throw new IllegalArgumentException(ERROR_DIFFER);
161         }
162 
163         /* Subtract the value */
164         super.subtractValue(pValue);
165     }
166 }