1 /*
2 * MoneyWise: Finance Application
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.moneywise.data.statics;
18
19 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
21 import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataClass;
22
23 /**
24 * Enumeration of Security Type Classes.
25 */
26 public enum MoneyWiseSecurityClass
27 implements PrometheusStaticDataClass {
28 /**
29 * Shares.
30 * <p>
31 * This is a share security and represents stock held in a company.
32 */
33 SHARES(1, 0),
34
35 /**
36 * Growth Unit Trust or OEIC.
37 * <p>
38 * This is a UnitTrust account and represents a mutual fund that reinvests income.
39 */
40 GROWTHUNITTRUST(2, 1),
41
42 /**
43 * Income Unit Trust or OEIC.
44 * <p>
45 * This is a UnitTrust account and represents a mutual fund that provides income.
46 */
47 INCOMEUNITTRUST(3, 2),
48
49 /**
50 * Life Bond.
51 * <p>
52 * This is a LifeBond account, which is a specialised form of an {@link #GROWTHUNITTRUST}
53 * security. It simply differs in tax treatment.
54 */
55 LIFEBOND(4, 3),
56
57 /**
58 * Endowment.
59 * <p>
60 * This is a Endowment account, which is a specialised form of an {@link #GROWTHUNITTRUST}
61 * security. It simply differs in tax treatment.
62 */
63 ENDOWMENT(5, 4),
64
65 /**
66 * Property.
67 * <p>
68 * This is a Property account, which represents an owned property.
69 */
70 PROPERTY(6, 5),
71
72 /**
73 * Vehicle.
74 * <p>
75 * This is a Vehicle account, which represents a road vehicle.
76 */
77 VEHICLE(7, 6),
78
79 /**
80 * Defined Contribution Pension Pot.
81 * <p>
82 * This is a defined contribution PensionPot. TaxFree contributions can be made to this Pot via
83 * an Income:Pension transaction. It should have a single unit valued at the size of the
84 * PensionPot.
85 */
86 DEFINEDCONTRIBUTION(8, 7),
87
88 /**
89 * DefinedBenefit PensionPot.
90 * <p>
91 * This is a defined Benefit Pension Pot. TaxFree contributions can be made to this Pot via an
92 * Income:Pension transaction. It should have a single unit valued at the annual income value.
93 * Its valuation is the annual income multiplied by 20.
94 */
95 DEFINEDBENEFIT(9, 8),
96
97 /**
98 * StatePension PensionPot.
99 * <p>
100 * This is a state Pension Pot. It should have a single unit valued at the weekly income value.
101 * Its valuation is the weekly income multiplied by 52*20. It is a singular Security.
102 */
103 STATEPENSION(10, 9),
104
105 /**
106 * StockOption.
107 * <p>
108 * This is stockOption. It relates to an option to buy a particular stock at a particular price
109 * at a later date.
110 */
111 STOCKOPTION(11, 10),
112
113 /**
114 * Generic Asset Account.
115 * <p>
116 * This is a generic asset account and represents items whose value is determined by the product
117 * of the number units held and the most recent unit price.
118 */
119 ASSET(12, 11);
120
121 /**
122 * Number of Pension Years for valuation.
123 */
124 private static final int PENSION_YEARS = 20;
125
126 /**
127 * Number of Pension Weeks for valuation.
128 */
129 private static final int PENSION_WEEKS = 52;
130
131 /**
132 * The String name.
133 */
134 private String theName;
135
136 /**
137 * Class Id.
138 */
139 private final int theId;
140
141 /**
142 * Class Order.
143 */
144 private final int theOrder;
145
146 /**
147 * Constructor.
148 *
149 * @param uId the Id
150 * @param uOrder the default order.
151 */
152 MoneyWiseSecurityClass(final int uId,
153 final int uOrder) {
154 theId = uId;
155 theOrder = uOrder;
156 }
157
158 @Override
159 public int getClassId() {
160 return theId;
161 }
162
163 @Override
164 public int getOrder() {
165 return theOrder;
166 }
167
168 @Override
169 public String toString() {
170 /* If we have not yet loaded the name */
171 if (theName == null) {
172 /* Load the name */
173 theName = MoneyWiseStaticResource.getKeyForSecurityType(this).getValue();
174 }
175
176 /* return the name */
177 return theName;
178 }
179
180 /**
181 * get value from id.
182 *
183 * @param id the id value
184 * @return the corresponding enum object
185 * @throws OceanusException on error
186 */
187 public static MoneyWiseSecurityClass fromId(final int id) throws OceanusException {
188 for (MoneyWiseSecurityClass myClass : values()) {
189 if (myClass.getClassId() == id) {
190 return myClass;
191 }
192 }
193 throw new MoneyWiseDataException("Invalid ClassId for " + MoneyWiseStaticDataType.SECURITYTYPE.toString() + ":" + id);
194 }
195
196 /**
197 * Determine whether the SecurityType is a pension.
198 *
199 * @return <code>true</code> if the security type is a pension, <code>false</code> otherwise.
200 */
201 public boolean isPension() {
202 switch (this) {
203 case DEFINEDBENEFIT:
204 case DEFINEDCONTRIBUTION:
205 case STATEPENSION:
206 return true;
207 default:
208 return false;
209 }
210 }
211
212 /**
213 * Determine whether the SecurityType is a dividend provider.
214 *
215 * @return <code>true</code> if the security type is a dividend provider, <code>false</code>
216 * otherwise.
217 */
218 public boolean isDividend() {
219 switch (this) {
220 case SHARES:
221 case INCOMEUNITTRUST:
222 case GROWTHUNITTRUST:
223 return true;
224 default:
225 return false;
226 }
227 }
228
229 /**
230 * Determine whether the SecurityType is shares.
231 *
232 * @return <code>true</code> if the security type is shares, <code>false</code> otherwise.
233 */
234 public boolean isShares() {
235 return this == SHARES;
236 }
237
238 /**
239 * Determine whether the SecurityType is option.
240 *
241 * @return <code>true</code> if the security type is option, <code>false</code> otherwise.
242 */
243 public boolean isOption() {
244 return this == STOCKOPTION;
245 }
246
247 /**
248 * Determine whether the SecurityType needs a symbol.
249 *
250 * @return <code>true</code> if the security type needs a symbol, <code>false</code> otherwise.
251 */
252 public boolean needsSymbol() {
253 switch (this) {
254 case SHARES:
255 case GROWTHUNITTRUST:
256 case INCOMEUNITTRUST:
257 case LIFEBOND:
258 return true;
259 default:
260 return false;
261 }
262 }
263
264 /**
265 * Determine whether the SecurityType needs a region.
266 *
267 * @return <code>true</code> if the security type needs a region, <code>false</code> otherwise.
268 */
269 public boolean needsRegion() {
270 switch (this) {
271 case INCOMEUNITTRUST:
272 case GROWTHUNITTRUST:
273 case LIFEBOND:
274 return true;
275 default:
276 return false;
277 }
278 }
279
280 /**
281 * Determine whether the SecurityType needs market as a parent.
282 *
283 * @return <code>true</code> if the security type needs market as a parent, <code>false</code>
284 * otherwise.
285 */
286 public boolean needsMarketParent() {
287 switch (this) {
288 case ASSET:
289 case PROPERTY:
290 case VEHICLE:
291 case ENDOWMENT:
292 return true;
293 default:
294 return false;
295 }
296 }
297
298 /**
299 * Determine whether the SecurityType can be tax free.
300 *
301 * @return <code>true</code> if the security type can be tax free, <code>false</code> otherwise.
302 */
303 public boolean canTaxFree() {
304 switch (this) {
305 case SHARES:
306 case INCOMEUNITTRUST:
307 case GROWTHUNITTRUST:
308 case PROPERTY:
309 return true;
310 default:
311 return false;
312 }
313 }
314
315 /**
316 * Determine whether the SecurityType is subject to Capital Gains.
317 *
318 * @return <code>true</code> if the security type is subject to Capital Gains,
319 * <code>false</code> otherwise.
320 */
321 public boolean isCapitalGains() {
322 switch (this) {
323 case SHARES:
324 case INCOMEUNITTRUST:
325 case GROWTHUNITTRUST:
326 case PROPERTY:
327 return true;
328 default:
329 return false;
330 }
331 }
332
333 /**
334 * Determine whether the SecurityType is subject to Residential Gains.
335 *
336 * @return <code>true</code> if the security type is subject to Residential Gains,
337 * <code>false</code> otherwise.
338 */
339 public boolean isResidentialGains() {
340 return this == PROPERTY;
341 }
342
343 /**
344 * Determine whether the SecurityType is subject to Chargeable Gains.
345 *
346 * @return <code>true</code> if the security type is subject to Chargeable Gains,
347 * <code>false</code> otherwise.
348 */
349 public boolean isChargeableGains() {
350 return this == LIFEBOND;
351 }
352
353 /**
354 * Determine whether the SecurityType is Capital.
355 *
356 * @return <code>true</code> if the security type is Capital, <code>false</code> otherwise.
357 */
358 public boolean isCapital() {
359 switch (this) {
360 case SHARES:
361 case LIFEBOND:
362 case INCOMEUNITTRUST:
363 case GROWTHUNITTRUST:
364 return true;
365 default:
366 return false;
367 }
368 }
369
370 /**
371 * Determine whether the SecurityType is UnitTrust.
372 *
373 * @return <code>true</code> if the security type is Capital, <code>false</code> otherwise.
374 */
375 public boolean isUnitTrust() {
376 switch (this) {
377 case INCOMEUNITTRUST:
378 case GROWTHUNITTRUST:
379 return true;
380 default:
381 return false;
382 }
383 }
384
385 /**
386 * Is this a statePension?
387 *
388 * @return <code>true</code> if the SecurityType is statePension, <code>false</code> otherwise.
389 */
390 public boolean isStatePension() {
391 return this == STATEPENSION;
392 }
393
394 /**
395 * Is this a singular security?.
396 *
397 * @return <code>true</code> if the SecurityType is singular, <code>false</code> otherwise.
398 */
399 public boolean isSingular() {
400 return isStatePension();
401 }
402
403 /**
404 * Is this an autoUnits?
405 *
406 * @return <code>true</code> if the SecurityType is an autoUnits, <code>false</code> otherwise.
407 */
408 public boolean isAutoUnits() {
409 switch (this) {
410 case ENDOWMENT:
411 case STATEPENSION:
412 case DEFINEDCONTRIBUTION:
413 case DEFINEDBENEFIT:
414 return true;
415 default:
416 return false;
417 }
418 }
419
420 /**
421 * Obtain autoUnits.
422 *
423 * @return the number of units for this security if active.
424 */
425 public int getAutoUnits() {
426 switch (this) {
427 case ENDOWMENT:
428 case DEFINEDCONTRIBUTION:
429 return 1;
430 case STATEPENSION:
431 return PENSION_YEARS * PENSION_WEEKS;
432 case DEFINEDBENEFIT:
433 return PENSION_YEARS;
434 default:
435 return 0;
436 }
437 }
438 }