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.decimal.OceanusRate;
21 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
22 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxClass;
23 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet.MoneyWiseTaxBand;
24 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxResource;
25
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
29
30
31
32
33 public abstract class MoneyWiseUKInterestScheme
34 extends MoneyWiseUKIncomeScheme {
35
36
37
38 static {
39 MetisFieldSet.newFieldSet(MoneyWiseUKInterestScheme.class);
40 }
41
42
43
44
45 protected MoneyWiseUKInterestScheme() {
46 }
47
48
49
50
51
52
53
54 protected abstract OceanusRate getTaxCreditRate(MoneyWiseUKTaxYear pTaxYear);
55
56 @Override
57 protected OceanusMoney adjustAllowances(final MoneyWiseUKTaxConfig pConfig,
58 final OceanusMoney pAmount) {
59
60 final OceanusMoney myRemaining = super.adjustAllowances(pConfig, pAmount);
61
62
63 if (myRemaining.isNonZero()) {
64
65 final OceanusMoney myInterest = adjustForAllowance(pConfig.getSavingsAllowance(), myRemaining);
66
67
68 adjustForAllowance(pConfig.getLoSavingsBand().getAmount(), myInterest);
69 }
70
71
72 return myRemaining;
73 }
74
75 @Override
76 protected OceanusMoney getAmountInAllowance(final MoneyWiseUKTaxConfig pConfig,
77 final OceanusMoney pAmount) {
78
79 OceanusMoney myAmount = super.getAmountInAllowance(pConfig, pAmount);
80
81
82 if (myAmount.compareTo(pAmount) < 0) {
83
84 final OceanusMoney myRemaining = new OceanusMoney(pAmount);
85 myRemaining.subtractAmount(myAmount);
86
87
88 final OceanusMoney myXtra = getAmountInBand(pConfig.getSavingsAllowance(), myRemaining);
89
90
91 myAmount = new OceanusMoney(myAmount);
92 myAmount.addAmount(myXtra);
93 }
94
95
96 return myAmount;
97 }
98
99
100
101
102
103
104 protected OceanusRate getBaseRate() {
105 return null;
106 }
107
108 @Override
109 protected Iterator<MoneyWiseTaxBand> taxBandIterator(final MoneyWiseUKTaxConfig pConfig,
110 final MoneyWiseTaxClass pBasis) {
111
112 final MoneyWiseTaxBand myLoBand = pConfig.getLoSavingsBand();
113 final OceanusMoney myLoAmount = myLoBand.getAmount();
114 OceanusRate myRate = getBaseRate();
115
116
117 final List<MoneyWiseTaxBand> myList = new ArrayList<>();
118
119
120 final Iterator<MoneyWiseTaxBand> myIterator = super.taxBandIterator(pConfig, pBasis);
121 MoneyWiseTaxBand myBasicBand = myIterator.next();
122 OceanusMoney myAmount = myBasicBand.getAmount();
123
124
125 if (this instanceof MoneyWiseUKInterestLoBaseRateScheme) {
126
127 myList.add(myBasicBand);
128
129
130 myBasicBand = myIterator.next();
131 myAmount = myBasicBand.getAmount();
132
133
134 } else if (myLoAmount.isNonZero()) {
135 myList.add(myLoBand);
136 myAmount = new OceanusMoney(myAmount);
137 myAmount.subtract(myLoAmount);
138 }
139
140
141 if (myRate == null) {
142 myRate = myBasicBand.getRate();
143 }
144 myList.add(new MoneyWiseTaxBand(myAmount, myRate));
145
146
147 while (myIterator.hasNext()) {
148 final MoneyWiseTaxBand myBand = myIterator.next();
149 myList.add(myBand);
150 }
151
152
153 return myList.iterator();
154 }
155
156
157
158
159 public static class MoneyWiseUKInterestAsIncomeScheme
160 extends MoneyWiseUKInterestScheme {
161
162
163
164 private static final MetisFieldSet<MoneyWiseUKInterestAsIncomeScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKInterestAsIncomeScheme.class);
165
166
167
168
169 public MoneyWiseUKInterestAsIncomeScheme() {
170 }
171
172 @Override
173 protected OceanusRate getTaxCreditRate(final MoneyWiseUKTaxYear pTaxYear) {
174 return pTaxYear.getTaxBands().getBasicTaxRate();
175 }
176
177 @Override
178 public MetisFieldSet<MoneyWiseUKInterestAsIncomeScheme> getDataFieldSet() {
179 return FIELD_DEFS;
180 }
181 }
182
183
184
185
186 public static class MoneyWiseUKInterestBaseRateScheme
187 extends MoneyWiseUKInterestScheme {
188
189
190
191 private static final MetisFieldSet<MoneyWiseUKInterestBaseRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKInterestBaseRateScheme.class);
192
193
194
195
196 static {
197 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_BASE_RATE, MoneyWiseUKInterestBaseRateScheme::getBaseRate);
198 }
199
200
201
202
203 private final OceanusRate theBaseRate;
204
205
206
207
208
209
210 protected MoneyWiseUKInterestBaseRateScheme(final OceanusRate pRate) {
211 theBaseRate = pRate;
212 }
213
214 @Override
215 protected OceanusRate getBaseRate() {
216 return theBaseRate;
217 }
218
219 @Override
220 protected OceanusRate getTaxCreditRate(final MoneyWiseUKTaxYear pTaxYear) {
221 return theBaseRate;
222 }
223
224 @Override
225 public MetisFieldSet<? extends MoneyWiseUKInterestBaseRateScheme> getDataFieldSet() {
226 return FIELD_DEFS;
227 }
228 }
229
230
231
232
233 public static class MoneyWiseUKInterestLoBaseRateScheme
234 extends MoneyWiseUKInterestBaseRateScheme {
235
236
237
238 private static final MetisFieldSet<MoneyWiseUKInterestLoBaseRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKInterestLoBaseRateScheme.class);
239
240
241
242
243
244
245 protected MoneyWiseUKInterestLoBaseRateScheme(final OceanusRate pRate) {
246 super(pRate);
247 }
248
249 @Override
250 public MetisFieldSet<MoneyWiseUKInterestLoBaseRateScheme> getDataFieldSet() {
251 return FIELD_DEFS;
252 }
253 }
254 }