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.metis.field.MetisFieldSet;
20 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxClass;
21 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet.MoneyWiseTaxBand;
22 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxResource;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
24 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
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 MoneyWiseUKInterestAsIncomeScheme() {
170
171 }
172
173 @Override
174 protected OceanusRate getTaxCreditRate(final MoneyWiseUKTaxYear pTaxYear) {
175 return pTaxYear.getTaxBands().getBasicTaxRate();
176 }
177
178 @Override
179 public MetisFieldSet<MoneyWiseUKInterestAsIncomeScheme> getDataFieldSet() {
180 return FIELD_DEFS;
181 }
182 }
183
184
185
186
187 public static class MoneyWiseUKInterestBaseRateScheme
188 extends MoneyWiseUKInterestScheme {
189
190
191
192 private static final MetisFieldSet<MoneyWiseUKInterestBaseRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKInterestBaseRateScheme.class);
193
194
195
196
197 static {
198 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_BASE_RATE, MoneyWiseUKInterestBaseRateScheme::getBaseRate);
199 }
200
201
202
203
204 private final OceanusRate theBaseRate;
205
206
207
208
209
210
211 protected MoneyWiseUKInterestBaseRateScheme(final OceanusRate pRate) {
212 theBaseRate = pRate;
213 }
214
215 @Override
216 protected OceanusRate getBaseRate() {
217 return theBaseRate;
218 }
219
220 @Override
221 protected OceanusRate getTaxCreditRate(final MoneyWiseUKTaxYear pTaxYear) {
222 return theBaseRate;
223 }
224
225 @Override
226 public MetisFieldSet<? extends MoneyWiseUKInterestBaseRateScheme> getDataFieldSet() {
227 return FIELD_DEFS;
228 }
229 }
230
231
232
233
234 public static class MoneyWiseUKInterestLoBaseRateScheme
235 extends MoneyWiseUKInterestBaseRateScheme {
236
237
238
239 private static final MetisFieldSet<MoneyWiseUKInterestLoBaseRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKInterestLoBaseRateScheme.class);
240
241
242
243
244
245
246 protected MoneyWiseUKInterestLoBaseRateScheme(final OceanusRate pRate) {
247 super(pRate);
248 }
249
250 @Override
251 public MetisFieldSet<MoneyWiseUKInterestLoBaseRateScheme> getDataFieldSet() {
252 return FIELD_DEFS;
253 }
254 }
255 }