1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.tax.uk;
18
19 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
20 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
21 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
22 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseMarginalReduction;
23 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet.MoneyWiseTaxBand;
24 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxResource;
25
26 import java.util.Iterator;
27
28
29
30
31 public class MoneyWiseUKSavingsAllowance
32 extends MoneyWiseUKBasicAllowance {
33
34
35
36 private static final MetisFieldSet<MoneyWiseUKSavingsAllowance> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKSavingsAllowance.class);
37
38
39
40
41 static {
42 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_SAVINGS, MoneyWiseUKSavingsAllowance::getSavingsAllowance);
43 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_DIVIDEND, MoneyWiseUKSavingsAllowance::getDividendAllowance);
44 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.LIMIT_ADDALLOWANCE, MoneyWiseUKSavingsAllowance::getAdditionalAllowanceLimit);
45 }
46
47
48
49
50 private final OceanusMoney theSavingsAllowance;
51
52
53
54
55 private final OceanusMoney theDividendAllowance;
56
57
58
59
60 private final OceanusMoney theAddAllowLimit;
61
62
63
64
65
66
67
68
69
70
71
72 protected MoneyWiseUKSavingsAllowance(final OceanusMoney pAllowance,
73 final OceanusMoney pRentalAllowance,
74 final OceanusMoney pCapitalAllowance,
75 final OceanusMoney pSavingsAllowance,
76 final OceanusMoney pDividendAllowance,
77 final OceanusMoney pAddAllowLimit) {
78 super(pAllowance, pRentalAllowance, pCapitalAllowance, MoneyWiseMarginalReduction.ONEINTWO);
79 theSavingsAllowance = pSavingsAllowance;
80 theDividendAllowance = pDividendAllowance;
81 theAddAllowLimit = pAddAllowLimit;
82 }
83
84
85
86
87
88
89 protected OceanusMoney getSavingsAllowance() {
90 return theSavingsAllowance;
91 }
92
93
94
95
96
97
98 protected OceanusMoney getDividendAllowance() {
99 return theDividendAllowance;
100 }
101
102
103
104
105
106
107 protected OceanusMoney getAdditionalAllowanceLimit() {
108 return theAddAllowLimit;
109 }
110
111 @Override
112 protected OceanusMoney calculateBasicAllowance(final MoneyWiseUKTaxConfig pConfig) {
113
114 OceanusMoney myAllowance = getAllowance();
115
116
117 final OceanusMoney myGross = pConfig.getGrossTaxable();
118 if (myGross.compareTo(theAddAllowLimit) > 0) {
119
120 final OceanusMoney myReduction = getMarginalReduction().calculateReduction(myGross, theAddAllowLimit);
121 myAllowance = new OceanusMoney(myAllowance);
122 myAllowance.subtractAmount(myReduction);
123
124
125 if (!myAllowance.isPositive()) {
126
127 myAllowance.setZero();
128 }
129 }
130
131
132 return myAllowance;
133 }
134
135 @Override
136 protected OceanusMoney calculateSavingsAllowance(final MoneyWiseUKTaxConfig pConfig) {
137
138 final OceanusMoney myGross = pConfig.getGrossTaxable();
139 final OceanusMoney myBoundary = new OceanusMoney(pConfig.getAllowance());
140
141
142 final MoneyWiseUKTaxBands myBands = pConfig.getTaxYear().getTaxBands();
143 final Iterator<MoneyWiseTaxBand> myIterator = myBands.getStandardSet().iterator();
144
145
146 if (myIterator.hasNext()) {
147
148 myBoundary.addAmount(myIterator.next().getAmount());
149 if (myBoundary.compareTo(myGross) >= 0) {
150 return theSavingsAllowance;
151 }
152 }
153
154
155 final OceanusMoney myAllowance = new OceanusMoney(theSavingsAllowance);
156 if (myIterator.hasNext()) {
157
158 myBoundary.addAmount(myIterator.next().getAmount());
159 if (myBoundary.compareTo(myGross) >= 0) {
160 myAllowance.divide(2);
161 return myAllowance;
162 }
163 }
164
165
166 myAllowance.setZero();
167 return theSavingsAllowance;
168 }
169
170 @Override
171 protected OceanusMoney calculateDividendAllowance() {
172 return theDividendAllowance;
173 }
174
175 @Override
176 public MetisFieldSet<MoneyWiseUKSavingsAllowance> getDataFieldSet() {
177 return FIELD_DEFS;
178 }
179
180 @Override
181 public String formatObject(final OceanusDataFormatter pFormatter) {
182 return FIELD_DEFS.getName();
183 }
184 }