View Javadoc
1   /*
2    * MoneyWise: Finance Application
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.moneywise.tax.uk;
18  
19  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
20  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
21  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
22  import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
23  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
24  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
25  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxClass;
26  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet;
27  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet.MoneyWiseTaxBand;
28  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxConfig;
29  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxResource;
30  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxSource;
31  
32  /**
33   * Tax configuration.
34   */
35  public class MoneyWiseUKTaxConfig
36          implements MetisFieldItem, MoneyWiseTaxConfig {
37      /**
38       * Local Report fields.
39       */
40      private static final MetisFieldSet<MoneyWiseUKTaxConfig> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKTaxConfig.class);
41  
42      /*
43       * Declare Fields.
44       */
45      static {
46          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXYEAR_NAME, MoneyWiseUKTaxConfig::getTaxYear);
47          FIELD_DEFS.declareLocalField(MoneyWiseStaticDataType.TAXBASIS, MoneyWiseUKTaxConfig::getTaxSource);
48          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXCONFIG_GROSS, MoneyWiseUKTaxConfig::getGrossTaxable);
49          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXCONFIG_PRESAVINGS, MoneyWiseUKTaxConfig::getGrossPreSavings);
50          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXCONFIG_BIRTHDAY, MoneyWiseUKTaxConfig::getBirthday);
51          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXCONFIG_AGE, MoneyWiseUKTaxConfig::getClientAge);
52          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXCONFIG_AGEALLOWANCE, MoneyWiseUKTaxConfig::hasAgeRelatedAllowance);
53          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_BASIC, MoneyWiseUKTaxConfig::getAllowance);
54          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_RENTAL, MoneyWiseUKTaxConfig::getRentalAllowance);
55          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_SAVINGS, MoneyWiseUKTaxConfig::getSavingsAllowance);
56          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_DIVIDEND, MoneyWiseUKTaxConfig::getDividendAllowance);
57          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_CAPITAL, MoneyWiseUKTaxConfig::getCapitalAllowance);
58          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXYEAR_BANDS, MoneyWiseUKTaxConfig::getTaxBands);
59          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.TAXBANDS_LOSAVINGS, MoneyWiseUKTaxConfig::getLoSavingsBand);
60      }
61  
62      /**
63       * TaxYear.
64       */
65      private final MoneyWiseUKTaxYear theTaxYear;
66  
67      /**
68       * The taxSource.
69       */
70      private final MoneyWiseTaxSource theTaxSource;
71  
72      /**
73       * Gross Taxable Income.
74       */
75      private final OceanusMoney theGrossTaxable;
76  
77      /**
78       * Gross PreSavings.
79       */
80      private final OceanusMoney theGrossPreSavings;
81  
82      /**
83       * The client birthday.
84       */
85      private final OceanusDate theBirthday;
86  
87      /**
88       * The client age in the tax year.
89       */
90      private final Integer theClientAge;
91  
92      /**
93       * Do we have an age related allowance.
94       */
95      private boolean hasAgeRelatedAllowance;
96  
97      /**
98       * Basic Allowance.
99       */
100     private final OceanusMoney theAllowance;
101 
102     /**
103      * Rental Allowance.
104      */
105     private final OceanusMoney theRentalAllowance;
106 
107     /**
108      * Savings Allowance.
109      */
110     private final OceanusMoney theSavingsAllowance;
111 
112     /**
113      * Dividend Allowance.
114      */
115     private final OceanusMoney theDividendAllowance;
116 
117     /**
118      * Capital Allowance.
119      */
120     private final OceanusMoney theCapitalAllowance;
121 
122     /**
123      * Tax Bands.
124      */
125     private final MoneyWiseTaxBandSet theTaxBands;
126 
127     /**
128      * LoSavings Band.
129      */
130     private final MoneyWiseTaxBand theLoSavings;
131 
132     /**
133      * Constructor.
134      *
135      * @param pTaxYear   the taxYear
136      * @param pTaxSource the tax source
137      * @param pBirthday  the client birthday
138      */
139     protected MoneyWiseUKTaxConfig(final MoneyWiseUKTaxYear pTaxYear,
140                                    final MoneyWiseTaxSource pTaxSource,
141                                    final OceanusDate pBirthday) {
142         /* Store details */
143         theTaxYear = pTaxYear;
144         theTaxSource = pTaxSource;
145         theBirthday = pBirthday;
146         theClientAge = theBirthday.ageOn(pTaxYear.getYearEnd());
147 
148         /* calculate the gross taxable income and preSavings */
149         theGrossPreSavings = determineGrossPreSavings();
150         theGrossTaxable = determineGrossTaxableIncome();
151 
152         /* Access the basic allowances */
153         final MoneyWiseUKBasicAllowance myAllowances = theTaxYear.getAllowances();
154 
155         /* Calculate the allowances */
156         theAllowance = new OceanusMoney(myAllowances.calculateBasicAllowance(this));
157         theRentalAllowance = new OceanusMoney(myAllowances.getRentalAllowance());
158         theSavingsAllowance = new OceanusMoney(myAllowances.calculateSavingsAllowance(this));
159         theDividendAllowance = new OceanusMoney(myAllowances.calculateDividendAllowance());
160         theCapitalAllowance = new OceanusMoney(myAllowances.getCapitalAllowance());
161 
162         /* Access the taxBands */
163         final MoneyWiseUKTaxBands myBands = theTaxYear.getTaxBands();
164         theTaxBands = new MoneyWiseTaxBandSet(myBands.getStandardSet());
165 
166         /* Calculate the loSavings band */
167         theLoSavings = myAllowances.calculateLoSavingsBand(this, myBands.getLoSavings());
168     }
169 
170     /**
171      * Constructor.
172      *
173      * @param pSource the source configuration
174      */
175     private MoneyWiseUKTaxConfig(final MoneyWiseUKTaxConfig pSource) {
176         /* Copy basic details */
177         theTaxYear = pSource.getTaxYear();
178         theTaxSource = pSource.getTaxSource();
179         theGrossTaxable = pSource.getGrossTaxable();
180         theGrossPreSavings = pSource.getGrossPreSavings();
181         theBirthday = pSource.getBirthday();
182         theClientAge = pSource.getClientAge();
183         hasAgeRelatedAllowance = pSource.hasAgeRelatedAllowance();
184 
185         /* Copy the allowances */
186         theAllowance = new OceanusMoney(pSource.getAllowance());
187         theRentalAllowance = new OceanusMoney(pSource.getRentalAllowance());
188         theSavingsAllowance = new OceanusMoney(pSource.getSavingsAllowance());
189         theDividendAllowance = new OceanusMoney(pSource.getDividendAllowance());
190         theCapitalAllowance = new OceanusMoney(pSource.getCapitalAllowance());
191 
192         /* Copy the taxBands */
193         theTaxBands = new MoneyWiseTaxBandSet(pSource.getTaxBands());
194         theLoSavings = new MoneyWiseTaxBand(pSource.getLoSavingsBand());
195     }
196 
197     /**
198      * Obtain the tax year.
199      *
200      * @return the tax year
201      */
202     public MoneyWiseUKTaxYear getTaxYear() {
203         return theTaxYear;
204     }
205 
206     /**
207      * Obtain the tax bases.
208      *
209      * @return the bases
210      */
211     public MoneyWiseTaxSource getTaxSource() {
212         return theTaxSource;
213     }
214 
215     /**
216      * Obtain the gross preSavings income.
217      *
218      * @return the gross preSavings
219      */
220     public OceanusMoney getGrossPreSavings() {
221         return theGrossPreSavings;
222     }
223 
224     /**
225      * Obtain the gross taxable income.
226      *
227      * @return the gross taxable
228      */
229     public OceanusMoney getGrossTaxable() {
230         return theGrossTaxable;
231     }
232 
233     /**
234      * Obtain the client birthday.
235      *
236      * @return the birthday
237      */
238     public OceanusDate getBirthday() {
239         return theBirthday;
240     }
241 
242     /**
243      * Obtain the client age.
244      *
245      * @return the gross taxable
246      */
247     public Integer getClientAge() {
248         return theClientAge;
249     }
250 
251     /**
252      * Do we have an age related allowance?
253      *
254      * @return true/false
255      */
256     public boolean hasAgeRelatedAllowance() {
257         return hasAgeRelatedAllowance;
258     }
259 
260     /**
261      * Set whether we have an age related allowance?
262      *
263      * @param pFlag true/false
264      */
265     protected void setHasAgeRelatedAllowance(final boolean pFlag) {
266         hasAgeRelatedAllowance = pFlag;
267     }
268 
269     /**
270      * Obtain the allowance.
271      *
272      * @return the allowance
273      */
274     public OceanusMoney getAllowance() {
275         return theAllowance;
276     }
277 
278     /**
279      * Obtain the rental allowance.
280      *
281      * @return the rental allowance
282      */
283     public OceanusMoney getRentalAllowance() {
284         return theRentalAllowance;
285     }
286 
287     /**
288      * Obtain the savings allowance.
289      *
290      * @return the allowance
291      */
292     public OceanusMoney getSavingsAllowance() {
293         return theSavingsAllowance;
294     }
295 
296     /**
297      * Obtain the dividend allowance.
298      *
299      * @return the allowance
300      */
301     public OceanusMoney getDividendAllowance() {
302         return theDividendAllowance;
303     }
304 
305     /**
306      * Obtain the capital allowance.
307      *
308      * @return the allowance
309      */
310     public OceanusMoney getCapitalAllowance() {
311         return theCapitalAllowance;
312     }
313 
314     /**
315      * Obtain the tax bands.
316      *
317      * @return the tax bands
318      */
319     public MoneyWiseTaxBandSet getTaxBands() {
320         return theTaxBands;
321     }
322 
323     /**
324      * Obtain the low savings band.
325      *
326      * @return the low savings band
327      */
328     public MoneyWiseTaxBand getLoSavingsBand() {
329         return theLoSavings;
330     }
331 
332     @Override
333     public MetisFieldSet<MoneyWiseUKTaxConfig> getDataFieldSet() {
334         return FIELD_DEFS;
335     }
336 
337     @Override
338     public String formatObject(final OceanusDataFormatter pFormatter) {
339         return FIELD_DEFS.getName();
340     }
341 
342     @Override
343     public MoneyWiseUKTaxConfig cloneIt() {
344         return new MoneyWiseUKTaxConfig(this);
345     }
346 
347     /**
348      * Determine the gross taxable income.
349      *
350      * @return the gross taxable income
351      */
352     private OceanusMoney determineGrossTaxableIncome() {
353         /* Initialise income to preSavings */
354         final OceanusMoney myIncome = new OceanusMoney(theGrossPreSavings);
355 
356         /* Add taxed interest to income */
357         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.TAXEDINTEREST));
358 
359         /* Add unTaxed interest to income */
360         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.UNTAXEDINTEREST));
361 
362         /* Add share dividends to income */
363         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.DIVIDEND));
364 
365         /* Add unit trust dividends to income */
366         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.UNITTRUSTDIVIDEND));
367 
368         /* Add foreign dividends to income */
369         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.FOREIGNDIVIDEND));
370 
371         /* Add chargeable gains to income */
372         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.CHARGEABLEGAINS));
373 
374         /* Capital Gains does not class as taxable income */
375 
376         /* Return the gross taxable amount */
377         return myIncome;
378     }
379 
380     /**
381      * Determine the gross preSavings income.
382      *
383      * @return the gross preSavings income
384      */
385     private OceanusMoney determineGrossPreSavings() {
386         /* Access the basic allowances */
387         final MoneyWiseUKBasicAllowance myAllowances = theTaxYear.getAllowances();
388 
389         /* Initialise income to correct currency */
390         final OceanusMoney myIncome = new OceanusMoney(myAllowances.getAllowance());
391         myIncome.setZero();
392 
393         /* Add the salary to income */
394         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.SALARY));
395 
396         /* Add the other income to income */
397         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.OTHERINCOME));
398 
399         /* Add the rental to income */
400         myIncome.addAmount(theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.RENTALINCOME));
401 
402         /* Access the room rental income */
403         final OceanusMoney myChargeable = theTaxSource.getAmountForTaxBasis(MoneyWiseTaxClass.ROOMRENTAL);
404 
405         /* If we have a chargeable element */
406         final OceanusMoney myAllowance = myAllowances.getRentalAllowance();
407         if (myChargeable.compareTo(myAllowance) > 0) {
408             /* Add the chargeable element to income */
409             myChargeable.subtractAmount(myAllowance);
410             myIncome.addAmount(myChargeable);
411         }
412 
413         /* Return the gross preSavings amount */
414         return myIncome;
415     }
416 }