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 MoneyWiseUKCapitalScheme
34 extends MoneyWiseUKIncomeScheme {
35
36
37
38 static {
39 MetisFieldSet.newFieldSet(MoneyWiseUKCapitalScheme.class);
40 }
41
42
43
44
45 protected MoneyWiseUKCapitalScheme() {
46 }
47
48 @Override
49 protected OceanusMoney adjustAllowances(final MoneyWiseUKTaxConfig pConfig,
50 final OceanusMoney pAmount) {
51
52 OceanusMoney myRemaining = adjustForAllowance(pConfig.getCapitalAllowance(), pAmount);
53
54
55 if (myRemaining.isNonZero()) {
56
57 myRemaining = super.adjustAllowances(pConfig, myRemaining);
58 }
59
60
61 return myRemaining;
62 }
63
64 @Override
65 protected OceanusMoney getAmountInAllowance(final MoneyWiseUKTaxConfig pConfig,
66 final OceanusMoney pAmount) {
67
68 OceanusMoney myAmount = getAmountInBand(pConfig.getCapitalAllowance(), pAmount);
69
70
71 if (myAmount.compareTo(pAmount) < 0) {
72
73 final OceanusMoney myRemaining = new OceanusMoney(pAmount);
74 myRemaining.subtractAmount(myAmount);
75
76
77 final OceanusMoney myXtra = super.getAmountInAllowance(pConfig, myRemaining);
78
79
80 myAmount = new OceanusMoney(myAmount);
81 myAmount.addAmount(myXtra);
82 }
83
84
85 return myAmount;
86 }
87
88
89
90
91 public static class MoneyWiseUKCapitalFlatRateScheme
92 extends MoneyWiseUKCapitalScheme {
93
94
95
96 private static final MetisFieldSet<MoneyWiseUKCapitalFlatRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKCapitalFlatRateScheme.class);
97
98
99
100
101 static {
102 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_BASE_RATE, MoneyWiseUKCapitalFlatRateScheme::getBasicRate);
103 }
104
105
106
107
108 private final OceanusRate theBaseRate;
109
110
111
112
113
114
115 protected MoneyWiseUKCapitalFlatRateScheme(final OceanusRate pRate) {
116 theBaseRate = pRate;
117 }
118
119
120
121
122
123
124 protected OceanusRate getBasicRate() {
125 return theBaseRate;
126 }
127
128 @Override
129 public MetisFieldSet<? extends MoneyWiseUKCapitalFlatRateScheme> getDataFieldSet() {
130 return FIELD_DEFS;
131 }
132
133 @Override
134 protected Iterator<MoneyWiseTaxBand> taxBandIterator(final MoneyWiseUKTaxConfig pConfig,
135 final MoneyWiseTaxClass pBasis) {
136
137 final List<MoneyWiseTaxBand> myList = new ArrayList<>();
138
139
140 myList.add(new MoneyWiseTaxBand(getBasicRate()));
141
142
143 return myList.iterator();
144 }
145 }
146
147
148
149
150 public static class MoneyWiseUKCapitalSplitRateScheme
151 extends MoneyWiseUKCapitalFlatRateScheme {
152
153
154
155 private static final MetisFieldSet<MoneyWiseUKCapitalSplitRateScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKCapitalSplitRateScheme.class);
156
157
158
159
160 static {
161 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_HIGH_RATE, MoneyWiseUKCapitalSplitRateScheme::getHighRate);
162 }
163
164
165
166
167 private final OceanusRate theHighRate;
168
169
170
171
172
173
174
175 protected MoneyWiseUKCapitalSplitRateScheme(final OceanusRate pRate,
176 final OceanusRate pHighRate) {
177 super(pRate);
178 theHighRate = pHighRate;
179 }
180
181
182
183
184
185
186 protected OceanusRate getHighRate() {
187 return theHighRate;
188 }
189
190 @Override
191 public MetisFieldSet<? extends MoneyWiseUKCapitalSplitRateScheme> getDataFieldSet() {
192 return FIELD_DEFS;
193 }
194
195 @Override
196 protected Iterator<MoneyWiseTaxBand> taxBandIterator(final MoneyWiseUKTaxConfig pConfig,
197 final MoneyWiseTaxClass pBasis) {
198
199 final List<MoneyWiseTaxBand> myList = new ArrayList<>();
200
201
202 final Iterator<MoneyWiseTaxBand> myIterator = super.taxBandIterator(pConfig, pBasis);
203 final MoneyWiseTaxBand myFirstBand = myIterator.next();
204
205
206 myList.add(new MoneyWiseTaxBand(myFirstBand.getAmount(), getBasicRate()));
207 myList.add(new MoneyWiseTaxBand(getHighRate()));
208
209
210 return myList.iterator();
211 }
212 }
213
214
215
216
217 public static class MoneyWiseUKCapitalAsIncomeScheme
218 extends MoneyWiseUKCapitalScheme {
219
220
221
222 private static final MetisFieldSet<MoneyWiseUKCapitalAsIncomeScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKCapitalAsIncomeScheme.class);
223
224
225
226
227 MoneyWiseUKCapitalAsIncomeScheme() {
228
229 }
230
231 @Override
232 public MetisFieldSet<MoneyWiseUKCapitalAsIncomeScheme> getDataFieldSet() {
233 return FIELD_DEFS;
234 }
235 }
236
237
238
239
240 public static class MoneyWiseUKCapitalResidentialScheme
241 extends MoneyWiseUKCapitalSplitRateScheme {
242
243
244
245 private static final MetisFieldSet<MoneyWiseUKCapitalResidentialScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKCapitalResidentialScheme.class);
246
247
248
249
250 static {
251 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_RESIDENTIAL, MoneyWiseUKCapitalResidentialScheme::getResidentialScheme);
252 }
253
254
255
256
257 private final MoneyWiseUKCapitalSplitRateScheme theResidential;
258
259
260
261
262
263
264
265
266
267 protected MoneyWiseUKCapitalResidentialScheme(final OceanusRate pRate,
268 final OceanusRate pHighRate,
269 final OceanusRate pResRate,
270 final OceanusRate pHighResRate) {
271 super(pRate, pHighRate);
272 theResidential = new MoneyWiseUKCapitalSplitRateScheme(pResRate, pHighResRate);
273 }
274
275
276
277
278
279
280 protected MoneyWiseUKCapitalSplitRateScheme getResidentialScheme() {
281 return theResidential;
282 }
283
284 @Override
285 public MetisFieldSet<MoneyWiseUKCapitalResidentialScheme> getDataFieldSet() {
286 return FIELD_DEFS;
287 }
288
289 @Override
290 protected Iterator<MoneyWiseTaxBand> taxBandIterator(final MoneyWiseUKTaxConfig pConfig,
291 final MoneyWiseTaxClass pBasis) {
292
293 return MoneyWiseTaxClass.RESIDENTIALGAINS.equals(pBasis)
294 ? theResidential.taxBandIterator(pConfig, pBasis)
295 : super.taxBandIterator(pConfig, pBasis);
296 }
297 }
298 }