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.moneywise.exc.MoneyWiseDataException;
20  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
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         return switch (this) {
203             case DEFINEDBENEFIT, DEFINEDCONTRIBUTION, STATEPENSION -> true;
204             default -> false;
205         };
206     }
207 
208     /**
209      * Determine whether the SecurityType is a dividend provider.
210      *
211      * @return <code>true</code> if the security type is a dividend provider, <code>false</code>
212      * otherwise.
213      */
214     public boolean isDividend() {
215         return switch (this) {
216             case SHARES, INCOMEUNITTRUST, GROWTHUNITTRUST -> true;
217             default -> false;
218         };
219     }
220 
221     /**
222      * Determine whether the SecurityType is shares.
223      *
224      * @return <code>true</code> if the security type is shares, <code>false</code> otherwise.
225      */
226     public boolean isShares() {
227         return this == SHARES;
228     }
229 
230     /**
231      * Determine whether the SecurityType is option.
232      *
233      * @return <code>true</code> if the security type is option, <code>false</code> otherwise.
234      */
235     public boolean isOption() {
236         return this == STOCKOPTION;
237     }
238 
239     /**
240      * Determine whether the SecurityType needs a symbol.
241      *
242      * @return <code>true</code> if the security type needs a symbol, <code>false</code> otherwise.
243      */
244     public boolean needsSymbol() {
245         return switch (this) {
246             case SHARES, GROWTHUNITTRUST, INCOMEUNITTRUST, LIFEBOND -> true;
247             default -> false;
248         };
249     }
250 
251     /**
252      * Determine whether the SecurityType needs a region.
253      *
254      * @return <code>true</code> if the security type needs a region, <code>false</code> otherwise.
255      */
256     public boolean needsRegion() {
257         return switch (this) {
258             case INCOMEUNITTRUST, GROWTHUNITTRUST, LIFEBOND -> true;
259             default -> false;
260         };
261     }
262 
263     /**
264      * Determine whether the SecurityType needs market as a parent.
265      *
266      * @return <code>true</code> if the security type needs market as a parent, <code>false</code>
267      * otherwise.
268      */
269     public boolean needsMarketParent() {
270         return switch (this) {
271             case ASSET, PROPERTY, VEHICLE, ENDOWMENT -> true;
272             default -> false;
273         };
274     }
275 
276     /**
277      * Determine whether the SecurityType can be tax free.
278      *
279      * @return <code>true</code> if the security type can be tax free, <code>false</code> otherwise.
280      */
281     public boolean canTaxFree() {
282         return switch (this) {
283             case SHARES, INCOMEUNITTRUST, GROWTHUNITTRUST, PROPERTY -> true;
284             default -> false;
285         };
286     }
287 
288     /**
289      * Determine whether the SecurityType is subject to Capital Gains.
290      *
291      * @return <code>true</code> if the security type is subject to Capital Gains,
292      * <code>false</code> otherwise.
293      */
294     public boolean isCapitalGains() {
295         return switch (this) {
296             case SHARES, INCOMEUNITTRUST, GROWTHUNITTRUST, PROPERTY -> true;
297             default -> false;
298         };
299     }
300 
301     /**
302      * Determine whether the SecurityType is subject to Residential Gains.
303      *
304      * @return <code>true</code> if the security type is subject to Residential Gains,
305      * <code>false</code> otherwise.
306      */
307     public boolean isResidentialGains() {
308         return this == PROPERTY;
309     }
310 
311     /**
312      * Determine whether the SecurityType is subject to Chargeable Gains.
313      *
314      * @return <code>true</code> if the security type is subject to Chargeable Gains,
315      * <code>false</code> otherwise.
316      */
317     public boolean isChargeableGains() {
318         return this == LIFEBOND;
319     }
320 
321     /**
322      * Determine whether the SecurityType is Capital.
323      *
324      * @return <code>true</code> if the security type is Capital, <code>false</code> otherwise.
325      */
326     public boolean isCapital() {
327         return switch (this) {
328             case SHARES, LIFEBOND, INCOMEUNITTRUST, GROWTHUNITTRUST -> true;
329             default -> false;
330         };
331     }
332 
333     /**
334      * Determine whether the SecurityType is UnitTrust.
335      *
336      * @return <code>true</code> if the security type is Capital, <code>false</code> otherwise.
337      */
338     public boolean isUnitTrust() {
339         return switch (this) {
340             case INCOMEUNITTRUST, GROWTHUNITTRUST -> true;
341             default -> false;
342         };
343     }
344 
345     /**
346      * Is this a statePension?
347      *
348      * @return <code>true</code> if the SecurityType is statePension, <code>false</code> otherwise.
349      */
350     public boolean isStatePension() {
351         return this == STATEPENSION;
352     }
353 
354     /**
355      * Is this a singular security?.
356      *
357      * @return <code>true</code> if the SecurityType is singular, <code>false</code> otherwise.
358      */
359     public boolean isSingular() {
360         return isStatePension();
361     }
362 
363     /**
364      * Is this an autoUnits?
365      *
366      * @return <code>true</code> if the SecurityType is an autoUnits, <code>false</code> otherwise.
367      */
368     public boolean isAutoUnits() {
369         return switch (this) {
370             case ENDOWMENT, STATEPENSION, DEFINEDCONTRIBUTION, DEFINEDBENEFIT -> true;
371             default -> false;
372         };
373     }
374 
375     /**
376      * Obtain autoUnits.
377      *
378      * @return the number of units for this security if active.
379      */
380     public int getAutoUnits() {
381         return switch (this) {
382             case ENDOWMENT, DEFINEDCONTRIBUTION -> 1;
383             case STATEPENSION -> PENSION_YEARS * PENSION_WEEKS;
384             case DEFINEDBENEFIT -> PENSION_YEARS;
385             default -> 0;
386         };
387     }
388 }