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.metis.field.MetisFieldItem;
20  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
21  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseMarginalReduction;
22  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxBandSet.MoneyWiseTaxBand;
23  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxResource;
24  import io.github.tonywasher.joceanus.moneywise.tax.uk.MoneyWiseUKTax.MoneyWiseUKBasicAllowanceCtl;
25  import io.github.tonywasher.joceanus.moneywise.tax.uk.MoneyWiseUKTax.MoneyWiseUKTaxConfigCtl;
26  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
27  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
28  
29  /**
30   * Basic UK Tax Allowance.
31   */
32  public abstract class MoneyWiseUKBasicAllowance
33          implements MetisFieldItem, MoneyWiseUKBasicAllowanceCtl {
34      /**
35       * Local Report fields.
36       */
37      private static final MetisFieldSet<MoneyWiseUKBasicAllowance> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseUKBasicAllowance.class);
38  
39      /*
40       * Declare Fields.
41       */
42      static {
43          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_BASIC, MoneyWiseUKBasicAllowance::getAllowance);
44          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_RENTAL, MoneyWiseUKBasicAllowance::getRentalAllowance);
45          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.ALLOWANCE_CAPITAL, MoneyWiseUKBasicAllowance::getCapitalAllowance);
46          FIELD_DEFS.declareLocalField(MoneyWiseTaxResource.MARGINAL_REDUCTION, MoneyWiseUKBasicAllowance::getMarginalReduction);
47      }
48  
49      /**
50       * Allowance.
51       */
52      private final OceanusMoney theAllowance;
53  
54      /**
55       * Rental Allowance.
56       */
57      private final OceanusMoney theRentalAllowance;
58  
59      /**
60       * Capital Allowance.
61       */
62      private final OceanusMoney theCapitalAllowance;
63  
64      /**
65       * Marginal Reduction Type.
66       */
67      private final MoneyWiseMarginalReduction theMarginalReduction;
68  
69      /**
70       * Constructor.
71       *
72       * @param pAllowance        the allowance
73       * @param pRentalAllowance  the rental allowance
74       * @param pCapitalAllowance the capital allowance
75       * @param pReduction        the marginal reduction
76       */
77      protected MoneyWiseUKBasicAllowance(final OceanusMoney pAllowance,
78                                          final OceanusMoney pRentalAllowance,
79                                          final OceanusMoney pCapitalAllowance,
80                                          final MoneyWiseMarginalReduction pReduction) {
81          theAllowance = pAllowance;
82          theRentalAllowance = pRentalAllowance;
83          theCapitalAllowance = pCapitalAllowance;
84          theMarginalReduction = pReduction;
85      }
86  
87      /**
88       * Constructor.
89       *
90       * @param pAllowance        the allowance
91       * @param pRentalAllowance  the rental allowance
92       * @param pCapitalAllowance the capital allowance
93       */
94      protected MoneyWiseUKBasicAllowance(final OceanusMoney pAllowance,
95                                          final OceanusMoney pRentalAllowance,
96                                          final OceanusMoney pCapitalAllowance) {
97          this(pAllowance, pRentalAllowance, pCapitalAllowance, MoneyWiseMarginalReduction.TWOINTHREE);
98      }
99  
100     @Override
101     public OceanusMoney getAllowance() {
102         return theAllowance;
103     }
104 
105     @Override
106     public OceanusMoney getRentalAllowance() {
107         return theRentalAllowance;
108     }
109 
110     @Override
111     public OceanusMoney getCapitalAllowance() {
112         return theCapitalAllowance;
113     }
114 
115     /**
116      * Obtain the marginal reduction.
117      *
118      * @return the Reduction
119      */
120     protected MoneyWiseMarginalReduction getMarginalReduction() {
121         return theMarginalReduction;
122     }
123 
124     @Override
125     public OceanusMoney calculateBasicAllowance(final MoneyWiseUKTaxConfigCtl pConfig) {
126         return getAllowance();
127     }
128 
129     @Override
130     public OceanusMoney calculateSavingsAllowance(final MoneyWiseUKTaxConfigCtl pConfig) {
131         return getZeroAmount();
132     }
133 
134     @Override
135     public OceanusMoney calculateDividendAllowance() {
136         return getZeroAmount();
137     }
138 
139     @Override
140     public MoneyWiseTaxBand calculateLoSavingsBand(final MoneyWiseUKTaxConfigCtl pConfig,
141                                                    final MoneyWiseTaxBand pLoSavings) {
142         /* Obtain the loSavings band */
143         if (pLoSavings == null) {
144             return new MoneyWiseTaxBand(getZeroAmount(), OceanusRate.getWholePercentage(0));
145         }
146         final MoneyWiseTaxBand myBand = new MoneyWiseTaxBand(pLoSavings);
147         final OceanusMoney myAmount = myBand.getAmount();
148 
149         /* Obtain the preSavings income remaining after the allowance */
150         final OceanusMoney myPreSavings = new OceanusMoney(pConfig.getGrossPreSavings());
151         myPreSavings.subtractAmount(pConfig.getAllowance());
152 
153         /* If we have allowance left over, return the full loSavings band */
154         if (!myPreSavings.isPositive()) {
155             return myBand;
156         }
157 
158         /* Subtract remaining income from the loSavings band */
159         myAmount.subtractAmount(myPreSavings);
160 
161         /* If we are negative, reset to zero */
162         if (!myAmount.isPositive()) {
163             myAmount.setZero();
164         }
165 
166         /* return the amount */
167         return myBand;
168     }
169 
170     /**
171      * Obtain zero amount.
172      *
173      * @return the zero amount
174      */
175     protected OceanusMoney getZeroAmount() {
176         /* Return a zero allowance */
177         final OceanusMoney myAllowance = new OceanusMoney(theAllowance);
178         myAllowance.setZero();
179         return myAllowance;
180     }
181 
182     /**
183      * Obtain the data fields.
184      *
185      * @return the data fields
186      */
187     protected static MetisFieldSet<? extends MoneyWiseUKBasicAllowance> getBaseFieldSet() {
188         return FIELD_DEFS;
189     }
190 }