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 }