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