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
22 /**
23 * Enumeration of TransactionCategory Classes.
24 */
25 public enum MoneyWiseTransCategoryClass
26 implements MoneyWiseCategoryInterface {
27 /**
28 * Taxed Salary Income.
29 */
30 TAXEDINCOME(1, 4),
31
32 /**
33 * Rental Income.
34 */
35 RENTALINCOME(2, 5),
36
37 /**
38 * RoomRental Income.
39 */
40 ROOMRENTALINCOME(3, 6),
41
42 /**
43 * Interest Income.
44 */
45 INTEREST(4, 7),
46
47 /**
48 * Dividend Income.
49 */
50 DIVIDEND(5, 8),
51
52 /**
53 * Virtual Income.
54 */
55 VIRTUALINCOME(6, 9),
56
57 /**
58 * GrossIncome.
59 */
60 GROSSINCOME(7, 10),
61
62 /**
63 * PensionContribution.
64 */
65 PENSIONCONTRIB(8, 11),
66
67 /**
68 * Gifted Income.
69 */
70 GIFTEDINCOME(9, 12),
71
72 /**
73 * Inheritance.
74 */
75 INHERITED(10, 13),
76
77 /**
78 * Interest earned on Loans.
79 */
80 LOANINTERESTEARNED(11, 14),
81
82 /**
83 * Loyalty Bonus.
84 */
85 LOYALTYBONUS(12, 15),
86
87 /**
88 * CashBack.
89 */
90 CASHBACK(13, 16),
91
92 /**
93 * Recovered Expenses.
94 */
95 RECOVEREDEXPENSES(14, 17),
96
97 /**
98 * Other Income.
99 */
100 OTHERINCOME(15, 18),
101
102 /**
103 * Stock Options Exercised.
104 */
105 OPTIONSEXERCISE(16, 19),
106
107 /**
108 * Stock Units Adjustment.
109 */
110 UNITSADJUST(17, 20),
111
112 /**
113 * Stock Split.
114 */
115 STOCKSPLIT(18, 21),
116
117 /**
118 * Stock DeMerger.
119 */
120 STOCKDEMERGER(19, 22),
121
122 /**
123 * Security Replacement.
124 */
125 SECURITYREPLACE(20, 23),
126
127 /**
128 * Security Closure.
129 */
130 SECURITYCLOSURE(21, 24),
131
132 /**
133 * Stock TakeOver.
134 */
135 STOCKTAKEOVER(22, 25),
136
137 /**
138 * Stock Rights Issue.
139 */
140 STOCKRIGHTSISSUE(23, 26),
141
142 /**
143 * PortfolioXfer.
144 */
145 PORTFOLIOXFER(24, 27),
146
147 /**
148 * Stock Options Granted.
149 */
150 OPTIONSGRANT(25, 28),
151
152 /**
153 * Stock Options Vested.
154 */
155 OPTIONSVEST(26, 29),
156
157 /**
158 * Stock Options Expired.
159 */
160 OPTIONSEXPIRE(27, 30),
161
162 /**
163 * Pension Drawdown.
164 */
165 PENSIONDRAWDOWN(28, 31),
166
167 /**
168 * Pension TaxFree.
169 */
170 PENSIONTAXFREE(29, 32),
171
172 /**
173 * Transfer.
174 */
175 TRANSFER(30, 33),
176
177 /**
178 * Expense.
179 */
180 EXPENSE(31, 34),
181
182 /**
183 * BadDebtCapital.
184 */
185 BADDEBTCAPITAL(32, 35),
186
187 /**
188 * BadDebtInterest.
189 */
190 BADDEBTINTEREST(33, 36),
191
192 /**
193 * LocalTaxes.
194 */
195 LOCALTAXES(34, 37),
196
197 /**
198 * Write Off.
199 */
200 WRITEOFF(35, 38),
201
202 /**
203 * Interest charged on Loans.
204 */
205 LOANINTERESTCHARGED(36, 39),
206
207 /**
208 * Rental Expense.
209 */
210 RENTALEXPENSE(37, 40),
211
212 /**
213 * AnnuityPurchase.
214 */
215 ANNUITYPURCHASE(38, 41),
216
217 /**
218 * Tax Relief.
219 */
220 TAXRELIEF(39, 42),
221
222 /**
223 * IncomeTax.
224 */
225 INCOMETAX(40, 43),
226
227 /**
228 * Taxed Interest.
229 */
230 TAXEDINTEREST(41, 44),
231
232 /**
233 * Gross Interest.
234 */
235 GROSSINTEREST(42, 45),
236
237 /**
238 * Tax Free Interest.
239 */
240 TAXFREEINTEREST(43, 46),
241
242 /**
243 * Peer2Peer Interest.
244 */
245 PEER2PEERINTEREST(44, 47),
246
247 /**
248 * Share Dividend Income.
249 */
250 SHAREDIVIDEND(45, 48),
251
252 /**
253 * Unit Trust Dividend Income.
254 */
255 UNITTRUSTDIVIDEND(46, 49),
256
257 /**
258 * Foreign Dividend.
259 */
260 FOREIGNDIVIDEND(47, 50),
261
262 /**
263 * Tax Free Dividend.
264 */
265 TAXFREEDIVIDEND(48, 51),
266
267 /**
268 * Taxed Loyalty Bonus.
269 */
270 TAXEDLOYALTYBONUS(49, 52),
271
272 /**
273 * Gross LoyaltyBonus.
274 */
275 GROSSLOYALTYBONUS(50, 53),
276
277 /**
278 * Tax Free LoyaltyBonus.
279 */
280 TAXFREELOYALTYBONUS(51, 54),
281
282 /**
283 * Chargeable Gain.
284 */
285 CHARGEABLEGAIN(52, 55),
286
287 /**
288 * Residential Gain.
289 */
290 RESIDENTIALGAIN(53, 56),
291
292 /**
293 * Capital Gain.
294 */
295 CAPITALGAIN(54, 57),
296
297 /**
298 * TaxFreeCapital Gain.
299 */
300 TAXFREEGAIN(55, 58),
301
302 /**
303 * Market Growth.
304 */
305 MARKETGROWTH(56, 59),
306
307 /**
308 * CurrencyFluctuation.
309 */
310 CURRENCYFLUCTUATION(57, 60),
311
312 /**
313 * Withheld.
314 * <p>
315 * This is a singular category catching withheld items such as charity donations associated with
316 * interest.
317 */
318 WITHHELD(58, 61),
319
320 /**
321 * OpeningBalance.
322 * <p>
323 * This is a singular category catching opening balances.
324 */
325 OPENINGBALANCE(59, 62),
326
327 /**
328 * EmployeeNatInsurance.
329 * <p>
330 * This is a singular category catching opening balances.
331 */
332 EMPLOYEENATINS(60, 63),
333
334 /**
335 * EmployeeNatInsurance.
336 * <p>
337 * This is a singular category catching opening balances.
338 */
339 EMPLOYERNATINS(61, 64),
340
341 /**
342 * Income Totals.
343 * <p>
344 * This is used for categories which simply own a set of income sub-categories and is used
345 * purely for reporting purposes.
346 */
347 INCOMETOTALS(62, 1),
348
349 /**
350 * Expense Totals.
351 * <p>
352 * This is used for categories which simply own a set of expense sub-categories and is used
353 * purely for reporting purposes.
354 */
355 EXPENSETOTALS(63, 2),
356
357 /**
358 * Security Parent.
359 * <p>
360 * This is used for categories which simply own a set of security transfer sub-categories and is
361 * used purely for holding purposes.
362 */
363 SECURITYPARENT(64, 3),
364
365 /**
366 * Totals.
367 * <p>
368 * This is used for the total of all non-transfer categories and is used purely for reporting
369 * purposes.
370 */
371 TOTALS(65, 0);
372
373 /**
374 * The String name.
375 */
376 private String theName;
377
378 /**
379 * Class Id.
380 */
381 private final int theId;
382
383 /**
384 * Class Order.
385 */
386 private final int theOrder;
387
388 /**
389 * Constructor.
390 *
391 * @param uId the id
392 * @param uOrder the default order.
393 */
394 MoneyWiseTransCategoryClass(final int uId,
395 final int uOrder) {
396 theId = uId;
397 theOrder = uOrder;
398 }
399
400 @Override
401 public int getClassId() {
402 return theId;
403 }
404
405 @Override
406 public int getOrder() {
407 return theOrder;
408 }
409
410 @Override
411 public String toString() {
412 /* If we have not yet loaded the name */
413 if (theName == null) {
414 /* Load the name */
415 theName = MoneyWiseStaticResource.getKeyForTransType(this).getValue();
416 }
417
418 /* return the name */
419 return theName;
420 }
421
422 /**
423 * get value from id.
424 *
425 * @param id the id value
426 * @return the corresponding enum object
427 * @throws OceanusException on error
428 */
429 public static MoneyWiseTransCategoryClass fromId(final int id) throws OceanusException {
430 for (MoneyWiseTransCategoryClass myClass : values()) {
431 if (myClass.getClassId() == id) {
432 return myClass;
433 }
434 }
435 throw new MoneyWiseDataException("Invalid ClassId for " + MoneyWiseStaticDataType.TRANSTYPE.toString() + ":" + id);
436 }
437
438 /**
439 * Determine whether the CategoryType is hidden type.
440 *
441 * @return <code>true</code> if the category is hidden, <code>false</code> otherwise.
442 */
443 public boolean isHiddenType() {
444 return switch (this) {
445 case SHAREDIVIDEND, UNITTRUSTDIVIDEND, FOREIGNDIVIDEND, TAXFREEDIVIDEND, TAXEDINTEREST, GROSSINTEREST,
446 TAXFREEINTEREST, PEER2PEERINTEREST, TAXEDLOYALTYBONUS, GROSSLOYALTYBONUS, TAXFREELOYALTYBONUS,
447 MARKETGROWTH, CURRENCYFLUCTUATION, WITHHELD, TAXRELIEF, CHARGEABLEGAIN, RESIDENTIALGAIN, CAPITALGAIN,
448 TAXFREEGAIN, VIRTUALINCOME, EMPLOYEENATINS, EMPLOYERNATINS, OPENINGBALANCE, TOTALS -> true;
449 default -> false;
450 };
451 }
452
453 /**
454 * Determine whether the Account is a secret payee.
455 *
456 * @return <code>true</code> if the category uses parent payee, <code>false</code> otherwise.
457 */
458 public boolean isSecretPayee() {
459 return switch (this) {
460 case INTEREST, DIVIDEND, CASHBACK, LOYALTYBONUS, LOANINTERESTEARNED, RENTALINCOME, ROOMRENTALINCOME,
461 WRITEOFF, LOANINTERESTCHARGED, OPTIONSEXERCISE -> true;
462 default -> false;
463 };
464 }
465
466 /**
467 * Determine whether the Account is a secret payee.
468 *
469 * @return <code>true</code> if the category uses parent payee, <code>false</code> otherwise.
470 */
471 public boolean isSwitchDirection() {
472 return switch (this) {
473 case INTEREST, DIVIDEND, CASHBACK, LOYALTYBONUS, RENTALINCOME, ROOMRENTALINCOME, WRITEOFF,
474 LOANINTERESTCHARGED, TRANSFER -> true;
475 default -> false;
476 };
477 }
478
479 /**
480 * Determine whether the category type is singular.
481 *
482 * @return <code>true</code> if the event category type is singular, <code>false</code>
483 * otherwise.
484 */
485 public boolean isSingular() {
486 return INCOMETAX.equals(this) || isHiddenType();
487 }
488
489 /**
490 * Determine whether the CategoryType is an income.
491 *
492 * @return <code>true</code> if the category is income, <code>false</code> otherwise.
493 */
494 public boolean isIncome() {
495 return switch (this) {
496 case TAXEDINCOME, VIRTUALINCOME, GROSSINCOME, PENSIONCONTRIB, LOYALTYBONUS, CASHBACK, OTHERINCOME,
497 RECOVEREDEXPENSES, GIFTEDINCOME, INTEREST, TAXEDINTEREST, GROSSINTEREST, TAXFREEINTEREST,
498 PEER2PEERINTEREST, DIVIDEND, SHAREDIVIDEND, UNITTRUSTDIVIDEND, FOREIGNDIVIDEND, TAXFREEDIVIDEND,
499 TAXEDLOYALTYBONUS, GROSSLOYALTYBONUS, TAXFREELOYALTYBONUS, INHERITED, LOANINTERESTEARNED, RENTALINCOME,
500 ROOMRENTALINCOME, OPTIONSEXERCISE, EMPLOYEENATINS, EMPLOYERNATINS, OPENINGBALANCE, INCOMETOTALS ->
501 true;
502 default -> false;
503 };
504 }
505
506 /**
507 * Determine whether the CategoryType is an expense.
508 *
509 * @return <code>true</code> if the category is expense, <code>false</code> otherwise.
510 */
511 public boolean isExpense() {
512 return !isIncome() && !isTransfer();
513 }
514
515 /**
516 * Determine whether the CategoryType is dilutable.
517 *
518 * @return <code>true</code> if the category is dilutable, <code>false</code> otherwise.
519 */
520 public boolean isDilutable() {
521 return switch (this) {
522 case STOCKSPLIT, STOCKDEMERGER -> true;
523 default -> false;
524 };
525 }
526
527 /**
528 * Determine whether the CategoryType is dividend.
529 *
530 * @return <code>true</code> if the category is dividend, <code>false</code> otherwise.
531 */
532 public boolean isDividend() {
533 return switch (this) {
534 case DIVIDEND, SHAREDIVIDEND, UNITTRUSTDIVIDEND, FOREIGNDIVIDEND, TAXFREEDIVIDEND -> true;
535 default -> false;
536 };
537 }
538
539 /**
540 * Determine whether the CategoryType is interest.
541 *
542 * @return <code>true</code> if the category is interest, <code>false</code> otherwise.
543 */
544 public boolean isInterest() {
545 return switch (this) {
546 case INTEREST, TAXEDINTEREST, GROSSINTEREST, TAXFREEINTEREST, PEER2PEERINTEREST -> true;
547 default -> false;
548 };
549 }
550
551 /**
552 * Determine whether the CategoryType needs debit and credit both to have units.
553 *
554 * @return <code>true</code> if the category needs dual units, <code>false</code> otherwise.
555 */
556 public boolean isStockAdjustment() {
557 return switch (this) {
558 case STOCKSPLIT, UNITSADJUST, STOCKDEMERGER, SECURITYREPLACE, STOCKTAKEOVER, PORTFOLIOXFER, OPTIONSGRANT,
559 OPTIONSVEST, OPTIONSEXPIRE -> true;
560 default -> false;
561 };
562 }
563
564 /**
565 * Determine whether the CategoryType has null Amount.
566 *
567 * @return <code>true</code> if the category needs null amount, <code>false</code> otherwise.
568 */
569 public boolean needsNullAmount() {
570 return switch (this) {
571 case STOCKSPLIT, UNITSADJUST, STOCKDEMERGER, STOCKTAKEOVER, PORTFOLIOXFER, OPTIONSGRANT, OPTIONSVEST,
572 OPTIONSEXPIRE, SECURITYREPLACE -> true;
573 default -> false;
574 };
575 }
576
577 /**
578 * Determine whether the EventCategoryType can be parent categories.
579 *
580 * @return <code>true</code> if the event category type can parent categories,
581 * <code>false</code> otherwise.
582 */
583 public boolean canParentCategory() {
584 return switch (this) {
585 case INCOMETOTALS, EXPENSETOTALS, SECURITYPARENT, TOTALS -> true;
586 default -> false;
587 };
588 }
589
590 /**
591 * Determine whether the EventCategoryType is a subTotal.
592 *
593 * @return <code>true</code> if the event category type is a subTotal, <code>false</code>
594 * otherwise.
595 */
596 public boolean isSubTotal() {
597 return switch (this) {
598 case INCOMETOTALS, EXPENSETOTALS, SECURITYPARENT -> true;
599 default -> false;
600 };
601 }
602
603 /**
604 * Is this event category a transfer?
605 *
606 * @return true/false
607 */
608 public boolean isTransfer() {
609 return this == TRANSFER || isSecurityTransfer();
610 }
611
612 /**
613 * Is this event category a NatInsurance event?
614 *
615 * @return true/false
616 */
617 public boolean isNatInsurance() {
618 return switch (this) {
619 case TAXEDINCOME, PENSIONCONTRIB -> true;
620 default -> false;
621 };
622 }
623
624 /**
625 * Is this event category a security transfer?
626 *
627 * @return true/false
628 */
629 public boolean isSecurityTransfer() {
630 return switch (this) {
631 case UNITSADJUST, STOCKSPLIT, STOCKDEMERGER, SECURITYREPLACE, STOCKTAKEOVER, STOCKRIGHTSISSUE,
632 PORTFOLIOXFER, OPTIONSGRANT, OPTIONSVEST, OPTIONSEXPIRE, SECURITYCLOSURE, SECURITYPARENT,
633 PENSIONDRAWDOWN, PENSIONTAXFREE -> true;
634 default -> false;
635 };
636 }
637
638 /**
639 * Is this event category a security closure?
640 *
641 * @return true/false
642 */
643 public boolean isSecurityClosure() {
644 return this == SECURITYCLOSURE;
645 }
646
647 @Override
648 public boolean isTotals() {
649 return this == TOTALS;
650 }
651 }