View Javadoc
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 }