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.tax;
18
19 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
20 import io.github.tonywasher.joceanus.oceanus.resource.OceanusBundleId;
21
22 import java.util.Currency;
23
24 /**
25 * Marginal allowance reduction.
26 */
27 public enum MoneyWiseMarginalReduction {
28 /**
29 * Half.
30 */
31 ONEINTWO(1, 2),
32
33 /**
34 * TwoThirds.
35 */
36 TWOINTHREE(2, 3);
37
38 /**
39 * The String name.
40 */
41 private String theName;
42
43 /**
44 * The multiplier.
45 */
46 private final int theMultiplier;
47
48 /**
49 * The quotient.
50 */
51 private final int theQuotient;
52
53 /**
54 * Constructor.
55 *
56 * @param pMultiplier the multiplier
57 * @param pQuotient the quotient
58 */
59 MoneyWiseMarginalReduction(final int pMultiplier,
60 final int pQuotient) {
61 theMultiplier = pMultiplier;
62 theQuotient = pQuotient;
63 }
64
65 @Override
66 public String toString() {
67 /* If we have not yet loaded the name */
68 if (theName == null) {
69 /* Load the name */
70 theName = bundleIdForReduction(this).getValue();
71 }
72
73 /* return the name */
74 return theName;
75 }
76
77 /**
78 * Calculate the allowance reduction.
79 *
80 * @param pGrossTaxable the gross taxable income
81 * @param pLimit the allowance limit
82 * @return the reduction
83 */
84 public OceanusMoney calculateReduction(final OceanusMoney pGrossTaxable,
85 final OceanusMoney pLimit) {
86 /* Determine the amount by which we are over the limit */
87 final OceanusMoney myExcess = new OceanusMoney(pGrossTaxable);
88 myExcess.subtractAmount(pLimit);
89
90 /* Determine the quotient and multiplier in the required currency */
91 final Currency myCurrency = myExcess.getCurrency();
92 final OceanusMoney myQuotient = OceanusMoney.getWholeUnits(theQuotient, myCurrency);
93 final OceanusMoney myMultiplier = OceanusMoney.getWholeUnits(theMultiplier, myCurrency);
94
95 /* Calculate the reduction */
96 myExcess.divide(myQuotient.unscaledValue());
97 myExcess.multiply(myMultiplier.unscaledValue());
98
99 /* return the reduction */
100 return myExcess;
101 }
102
103 /**
104 * Obtain the resource bundleId for the reduction.
105 *
106 * @param pReduction the reduction
107 * @return the resource bundleId
108 */
109 private static OceanusBundleId bundleIdForReduction(final MoneyWiseMarginalReduction pReduction) {
110 return switch (pReduction) {
111 case ONEINTWO -> MoneyWiseTaxResource.MARGINAL_ONEINTWO;
112 case TWOINTHREE -> MoneyWiseTaxResource.MARGINAL_TWOINTHREE;
113 default -> throw new IllegalArgumentException();
114 };
115 }
116 }