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 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 public MoneyWiseUKCapitalAsIncomeScheme() {
228 }
229
230 @Override
231 public MetisFieldSet<MoneyWiseUKCapitalAsIncomeScheme> getDataFieldSet() {
232 return FIELD_DEFS;
233 }
234 }
235
236
237
238
239 public static class MoneyWiseUKCapitalResidentialScheme
240 extends MoneyWiseUKCapitalSplitRateScheme {
241
242
243
244 private static final MetisFieldSet<MoneyWiseUKCapitalResidentialScheme> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKCapitalResidentialScheme.class);
245
246
247
248
249 static {
250 FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.SCHEME_RESIDENTIAL, MoneyWiseUKCapitalResidentialScheme::getResidentialScheme);
251 }
252
253
254
255
256 private final MoneyWiseUKCapitalSplitRateScheme theResidential;
257
258
259
260
261
262
263
264
265
266 protected MoneyWiseUKCapitalResidentialScheme(final OceanusRate pRate,
267 final OceanusRate pHighRate,
268 final OceanusRate pResRate,
269 final OceanusRate pHighResRate) {
270 super(pRate, pHighRate);
271 theResidential = new MoneyWiseUKCapitalSplitRateScheme(pResRate, pHighResRate);
272 }
273
274
275
276
277
278
279 protected MoneyWiseUKCapitalSplitRateScheme getResidentialScheme() {
280 return theResidential;
281 }
282
283 @Override
284 public MetisFieldSet<MoneyWiseUKCapitalResidentialScheme> getDataFieldSet() {
285 return FIELD_DEFS;
286 }
287
288 @Override
289 protected Iterator<MoneyWiseTaxBand> taxBandIterator(final MoneyWiseUKTaxConfig pConfig,
290 final MoneyWiseTaxClass pBasis) {
291
292 return MoneyWiseTaxClass.RESIDENTIALGAINS.equals(pBasis)
293 ? theResidential.taxBandIterator(pConfig, pBasis)
294 : super.taxBandIterator(pConfig, pBasis);
295 }
296 }
297 }