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.atlas.data.analysis.buckets;
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.metis.preference.MetisPreferenceManager;
22  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.base.MoneyWiseXAnalysisEventList;
23  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisCashBucket.MoneyWiseXAnalysisCashBucketList;
24  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisCashCategoryBucket.MoneyWiseXAnalysisCashCategoryBucketList;
25  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositBucket.MoneyWiseXAnalysisDepositBucketList;
26  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisDepositCategoryBucket.MoneyWiseXAnalysisDepositCategoryBucketList;
27  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisInterfaces.MoneyWiseXAnalysisCursor;
28  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisLoanBucket.MoneyWiseXAnalysisLoanBucketList;
29  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisLoanCategoryBucket.MoneyWiseXAnalysisLoanCategoryBucketList;
30  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisPayeeBucket.MoneyWiseXAnalysisPayeeBucketList;
31  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisPortfolioBucket.MoneyWiseXAnalysisPortfolioBucketList;
32  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisTaxBasisBucket.MoneyWiseXAnalysisTaxBasisBucketList;
33  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisTransCategoryBucket.MoneyWiseXAnalysisTransCategoryBucketList;
34  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisTransTagBucket.MoneyWiseXAnalysisTransTagBucketList;
35  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisAccountAttr;
36  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisPayeeAttr;
37  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisSecurityAttr;
38  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisTaxBasisAttr;
39  import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisTransAttr;
40  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
41  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
42  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataSet;
43  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
44  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
45  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxAnalysis;
46  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxYear;
47  import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxYearCache;
48  import io.github.tonywasher.joceanus.moneywise.tax.uk.MoneyWiseUKTaxYearCache;
49  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
50  import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
51  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
52  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
53  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogManager;
54  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogger;
55  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
56  
57  /**
58   * Data Analysis.
59   *
60   * @author Tony Washer
61   */
62  public class MoneyWiseXAnalysis
63          implements MetisFieldItem, MoneyWiseXAnalysisHolder {
64      /**
65       * Logger.
66       */
67      private static final OceanusLogger LOGGER = OceanusLogManager.getLogger(MoneyWiseXAnalysis.class);
68  
69      /**
70       * Local Report fields.
71       */
72      private static final MetisFieldSet<MoneyWiseXAnalysis> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseXAnalysis.class);
73  
74      /*
75       * Declare Fields.
76       */
77      static {
78          FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_RANGE, MoneyWiseXAnalysis::getDateRange);
79          FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.TAX_YEARS, MoneyWiseXAnalysis::getTaxYearCache);
80          FIELD_DEFS.declareLocalField(MoneyWiseStaticDataType.CURRENCY, MoneyWiseXAnalysis::getCurrency);
81          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.DEPOSIT.getListId(), MoneyWiseXAnalysis::getDeposits);
82          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.CASH.getListId(), MoneyWiseXAnalysis::getCash);
83          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.LOAN.getListId(), MoneyWiseXAnalysis::getLoans);
84          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.PAYEE.getListId(), MoneyWiseXAnalysis::getPayees);
85          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.PORTFOLIO.getListId(), MoneyWiseXAnalysis::getPortfolios);
86          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.DEPOSITCATEGORY.getListId(), MoneyWiseXAnalysis::getDepositCategories);
87          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.CASHCATEGORY.getListId(), MoneyWiseXAnalysis::getCashCategories);
88          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.LOANCATEGORY.getListId(), MoneyWiseXAnalysis::getLoanCategories);
89          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.TRANSCATEGORY.getListId(), MoneyWiseXAnalysis::getTransCategories);
90          FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.TRANSTAG.getListId(), MoneyWiseXAnalysis::getTransactionTags);
91          FIELD_DEFS.declareLocalField(MoneyWiseStaticDataType.TAXBASIS.getListId(), MoneyWiseXAnalysis::getTaxBasis);
92          FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.TAX_CALCULATION, MoneyWiseXAnalysis::getTaxAnalysis);
93      }
94  
95      /**
96       * The EditSet.
97       */
98      private final PrometheusEditSet theEditSet;
99  
100     /**
101      * The Cursor.
102      */
103     private final MoneyWiseXAnalysisCursor theCursor;
104 
105     /**
106      * The taxYear cache.
107      */
108     private final MoneyWiseTaxYearCache theTaxYearCache;
109 
110     /**
111      * The Currency.
112      */
113     private final MoneyWiseCurrency theCurrency;
114 
115     /**
116      * The Preference Manager.
117      */
118     private final MetisPreferenceManager thePreferences;
119 
120     /**
121      * The DataRange.
122      */
123     private final OceanusDateRange theDateRange;
124 
125     /**
126      * The deposit buckets.
127      */
128     private final MoneyWiseXAnalysisDepositBucketList theDeposits;
129 
130     /**
131      * The cash buckets.
132      */
133     private final MoneyWiseXAnalysisCashBucketList theCash;
134 
135     /**
136      * The loan buckets.
137      */
138     private final MoneyWiseXAnalysisLoanBucketList theLoans;
139 
140     /**
141      * The payee buckets.
142      */
143     private final MoneyWiseXAnalysisPayeeBucketList thePayees;
144 
145     /**
146      * The portfolio buckets.
147      */
148     private final MoneyWiseXAnalysisPortfolioBucketList thePortfolios;
149 
150     /**
151      * The deposit category buckets.
152      */
153     private final MoneyWiseXAnalysisDepositCategoryBucketList theDepositCategories;
154 
155     /**
156      * The cash category buckets.
157      */
158     private final MoneyWiseXAnalysisCashCategoryBucketList theCashCategories;
159 
160     /**
161      * The loan category buckets.
162      */
163     private final MoneyWiseXAnalysisLoanCategoryBucketList theLoanCategories;
164 
165     /**
166      * The transaction category buckets.
167      */
168     private final MoneyWiseXAnalysisTransCategoryBucketList theTransCategories;
169 
170     /**
171      * The TransactionTag buckets.
172      */
173     private final MoneyWiseXAnalysisTransTagBucketList theTransTags;
174 
175     /**
176      * The tax basis buckets.
177      */
178     private final MoneyWiseXAnalysisTaxBasisBucketList theTaxBasis;
179 
180     /**
181      * The new tax calculations.
182      */
183     private final MoneyWiseTaxAnalysis theTaxAnalysis;
184 
185     /**
186      * The Events.
187      */
188     private MoneyWiseXAnalysisEventList theEvents;
189 
190     /**
191      * Do we have active securities?
192      */
193     private Boolean haveActiveSecurities = Boolean.FALSE;
194 
195     /**
196      * Do we have a foreign account?
197      */
198     private Boolean haveForeignCurrency = Boolean.FALSE;
199 
200     /**
201      * Constructor for a full analysis.
202      *
203      * @param pEditSet       the editSet to analyse events for
204      * @param pCursor        the cursor
205      * @param pPreferenceMgr the preference manager
206      */
207     public MoneyWiseXAnalysis(final PrometheusEditSet pEditSet,
208                               final MoneyWiseXAnalysisCursor pCursor,
209                               final MetisPreferenceManager pPreferenceMgr) {
210         /* Store the data */
211         theEditSet = pEditSet;
212         theCursor = pCursor;
213         final MoneyWiseDataSet myDataSet = getData();
214         theCurrency = myDataSet.getReportingCurrency();
215         thePreferences = pPreferenceMgr;
216         theDateRange = myDataSet.getDateRange();
217 
218         /* Access the TaxYearCache */
219         theTaxYearCache = (MoneyWiseUKTaxYearCache) myDataSet.getTaxFactory();
220 
221         /* Create a new set of buckets */
222         theDeposits = new MoneyWiseXAnalysisDepositBucketList(this);
223         theCash = new MoneyWiseXAnalysisCashBucketList(this);
224         theLoans = new MoneyWiseXAnalysisLoanBucketList(this);
225         thePortfolios = new MoneyWiseXAnalysisPortfolioBucketList(this);
226         thePayees = new MoneyWiseXAnalysisPayeeBucketList(this);
227         theTaxBasis = new MoneyWiseXAnalysisTaxBasisBucketList(this);
228         theTransCategories = new MoneyWiseXAnalysisTransCategoryBucketList(this);
229         theTransTags = new MoneyWiseXAnalysisTransTagBucketList(this);
230 
231         /* Create totalling buckets */
232         theDepositCategories = new MoneyWiseXAnalysisDepositCategoryBucketList(this);
233         theCashCategories = new MoneyWiseXAnalysisCashCategoryBucketList(this);
234         theLoanCategories = new MoneyWiseXAnalysisLoanCategoryBucketList(this);
235         theTaxAnalysis = null;
236     }
237 
238     /**
239      * Constructor for a dated analysis.
240      *
241      * @param pBase the base analysis
242      * @param pDate the date for the analysis
243      */
244     public MoneyWiseXAnalysis(final MoneyWiseXAnalysis pBase,
245                               final OceanusDate pDate) {
246         /* Store the data */
247         theEditSet = pBase.getEditSet();
248         final MoneyWiseDataSet myDataSet = getData();
249         theCurrency = pBase.getCurrency();
250         thePreferences = pBase.getPreferenceMgr();
251         theDateRange = new OceanusDateRange(myDataSet.getDateRange().getStart(), pDate);
252         theEvents = pBase.getEvents();
253         theCursor = null;
254 
255         /* Access the TaxYearCache */
256         theTaxYearCache = (MoneyWiseUKTaxYearCache) myDataSet.getTaxFactory();
257 
258         /* Create a new set of buckets */
259         theDeposits = new MoneyWiseXAnalysisDepositBucketList(this, pBase.getDeposits(), pDate);
260         theCash = new MoneyWiseXAnalysisCashBucketList(this, pBase.getCash(), pDate);
261         theLoans = new MoneyWiseXAnalysisLoanBucketList(this, pBase.getLoans(), pDate);
262         thePortfolios = new MoneyWiseXAnalysisPortfolioBucketList(this, pBase.getPortfolios(), pDate);
263         thePayees = new MoneyWiseXAnalysisPayeeBucketList(this, pBase.getPayees(), pDate);
264         theTaxBasis = new MoneyWiseXAnalysisTaxBasisBucketList(this, pBase.getTaxBasis(), pDate);
265         theTransCategories = new MoneyWiseXAnalysisTransCategoryBucketList(this, pBase.getTransCategories(), pDate);
266         theTransTags = new MoneyWiseXAnalysisTransTagBucketList(this, pBase.getTransactionTags(), pDate);
267 
268         /* Create totalling buckets */
269         theDepositCategories = new MoneyWiseXAnalysisDepositCategoryBucketList(this);
270         theCashCategories = new MoneyWiseXAnalysisCashCategoryBucketList(this);
271         theLoanCategories = new MoneyWiseXAnalysisLoanCategoryBucketList(this);
272         theTaxAnalysis = null;
273     }
274 
275     /**
276      * Constructor for a ranged analysis.
277      *
278      * @param pBase  the base analysis
279      * @param pRange the range for the analysis
280      */
281     public MoneyWiseXAnalysis(final MoneyWiseXAnalysis pBase,
282                               final OceanusDateRange pRange) {
283         /* Store the data */
284         theEditSet = pBase.getEditSet();
285         final MoneyWiseDataSet myDataSet = getData();
286         theCurrency = pBase.getCurrency();
287         thePreferences = pBase.getPreferenceMgr();
288         theDateRange = pRange;
289         theEvents = pBase.getEvents();
290         theCursor = null;
291 
292         /* Access the TaxYearCache */
293         theTaxYearCache = (MoneyWiseUKTaxYearCache) myDataSet.getTaxFactory();
294 
295         /* Create a new set of buckets */
296         theDeposits = new MoneyWiseXAnalysisDepositBucketList(this, pBase.getDeposits(), pRange);
297         theCash = new MoneyWiseXAnalysisCashBucketList(this, pBase.getCash(), pRange);
298         theLoans = new MoneyWiseXAnalysisLoanBucketList(this, pBase.getLoans(), pRange);
299         thePortfolios = new MoneyWiseXAnalysisPortfolioBucketList(this, pBase.getPortfolios(), pRange);
300         thePayees = new MoneyWiseXAnalysisPayeeBucketList(this, pBase.getPayees(), pRange);
301         theTaxBasis = new MoneyWiseXAnalysisTaxBasisBucketList(this, pBase.getTaxBasis(), pRange);
302         theTransCategories = new MoneyWiseXAnalysisTransCategoryBucketList(this, pBase.getTransCategories(), pRange);
303         theTransTags = new MoneyWiseXAnalysisTransTagBucketList(this, pBase.getTransactionTags(), pRange);
304 
305         /* Create totalling buckets */
306         theDepositCategories = new MoneyWiseXAnalysisDepositCategoryBucketList(this);
307         theCashCategories = new MoneyWiseXAnalysisCashCategoryBucketList(this);
308         theLoanCategories = new MoneyWiseXAnalysisLoanCategoryBucketList(this);
309 
310         /* Handle new tax calculations */
311         final MoneyWiseTaxYear myYear = (MoneyWiseTaxYear) theTaxYearCache.findTaxYearForRange(theDateRange);
312         theTaxAnalysis = myYear != null
313                 ? myYear.analyseTaxYear(thePreferences, theTaxBasis)
314                 : null;
315     }
316 
317     /**
318      * Is the analysis manager idle?
319      *
320      * @return true/false
321      */
322     public boolean isIdle() {
323         return theCurrency == null;
324     }
325 
326     @Override
327     public MetisFieldSet<MoneyWiseXAnalysis> getDataFieldSet() {
328         return FIELD_DEFS;
329     }
330 
331     @Override
332     public String formatObject(final OceanusDataFormatter pFormatter) {
333         return FIELD_DEFS.getName();
334     }
335 
336     /**
337      * Do we have a foreign currency?
338      *
339      * @return true/false
340      */
341     public Boolean haveForeignCurrency() {
342         return haveForeignCurrency;
343     }
344 
345     /**
346      * Do we have active securities?
347      *
348      * @return true/false
349      */
350     public Boolean haveActiveSecurities() {
351         return haveActiveSecurities;
352     }
353 
354     @Override
355     public PrometheusEditSet getEditSet() {
356         return theEditSet;
357     }
358 
359     /**
360      * Obtain the events.
361      *
362      * @return the events
363      */
364     public MoneyWiseXAnalysisEventList getEvents() {
365         return theEvents;
366     }
367 
368     /**
369      * Set the events.
370      *
371      * @param pEvents the events
372      */
373     public void setEvents(final MoneyWiseXAnalysisEventList pEvents) {
374         theEvents = pEvents;
375     }
376 
377     /**
378      * Obtain the cursor.
379      *
380      * @return the cursor
381      */
382     public MoneyWiseXAnalysisCursor getCursor() {
383         return theCursor;
384     }
385 
386     @Override
387     public MoneyWiseDataSet getData() {
388         return (MoneyWiseDataSet) theEditSet.getDataSet();
389     }
390 
391     /**
392      * Obtain the currency.
393      *
394      * @return the currency
395      */
396     private MoneyWiseTaxYearCache getTaxYearCache() {
397         return theTaxYearCache;
398     }
399 
400     @Override
401     public MoneyWiseCurrency getCurrency() {
402         return theCurrency;
403     }
404 
405     /**
406      * Obtain the preference manager.
407      *
408      * @return the data
409      */
410     public MetisPreferenceManager getPreferenceMgr() {
411         return thePreferences;
412     }
413 
414     @Override
415     public OceanusDateRange getDateRange() {
416         return theDateRange;
417     }
418 
419     /**
420      * Is this a ranged analysis?
421      *
422      * @return true/false
423      */
424     public boolean isRangedAnalysis() {
425         return theDateRange.getStart() == null;
426     }
427 
428     /**
429      * Obtain the deposit buckets list.
430      *
431      * @return the list
432      */
433     public MoneyWiseXAnalysisDepositBucketList getDeposits() {
434         return theDeposits;
435     }
436 
437     /**
438      * Obtain the cash buckets list.
439      *
440      * @return the list
441      */
442     public MoneyWiseXAnalysisCashBucketList getCash() {
443         return theCash;
444     }
445 
446     /**
447      * Obtain the loan buckets list.
448      *
449      * @return the list
450      */
451     public MoneyWiseXAnalysisLoanBucketList getLoans() {
452         return theLoans;
453     }
454 
455     /**
456      * Obtain the portfolio buckets list.
457      *
458      * @return the list
459      */
460     public MoneyWiseXAnalysisPortfolioBucketList getPortfolios() {
461         return thePortfolios;
462     }
463 
464     /**
465      * Obtain the payee buckets list.
466      *
467      * @return the list
468      */
469     public MoneyWiseXAnalysisPayeeBucketList getPayees() {
470         return thePayees;
471     }
472 
473     /**
474      * Obtain the deposit categories list.
475      *
476      * @return the list
477      */
478     public MoneyWiseXAnalysisDepositCategoryBucketList getDepositCategories() {
479         return theDepositCategories;
480     }
481 
482     /**
483      * Obtain the cash categories list.
484      *
485      * @return the list
486      */
487     public MoneyWiseXAnalysisCashCategoryBucketList getCashCategories() {
488         return theCashCategories;
489     }
490 
491     /**
492      * Obtain the loan categories list.
493      *
494      * @return the list
495      */
496     public MoneyWiseXAnalysisLoanCategoryBucketList getLoanCategories() {
497         return theLoanCategories;
498     }
499 
500     /**
501      * Obtain the transaction categories list.
502      *
503      * @return the list
504      */
505     public MoneyWiseXAnalysisTransCategoryBucketList getTransCategories() {
506         return theTransCategories;
507     }
508 
509     /**
510      * Obtain the transactionTag list.
511      *
512      * @return the list
513      */
514     public MoneyWiseXAnalysisTransTagBucketList getTransactionTags() {
515         return theTransTags;
516     }
517 
518     /**
519      * Obtain the tax basis list.
520      *
521      * @return the list
522      */
523     public MoneyWiseXAnalysisTaxBasisBucketList getTaxBasis() {
524         return theTaxBasis;
525     }
526 
527     /**
528      * Obtain the tax analysis.
529      *
530      * @return the analysis
531      */
532     public MoneyWiseTaxAnalysis getTaxAnalysis() {
533         return theTaxAnalysis;
534     }
535 
536     /**
537      * Produce Totals.
538      */
539     public void produceTotals() {
540         /* Analyse the deposits */
541         theDepositCategories.analyseDeposits(theDeposits);
542         theDepositCategories.produceTotals();
543         haveForeignCurrency = theDepositCategories.haveForeignCurrency();
544 
545         /* Analyse the cash */
546         theCashCategories.analyseCash(theCash);
547         theCashCategories.produceTotals();
548         haveForeignCurrency |= theCashCategories.haveForeignCurrency();
549 
550         /* Analyse the loans */
551         theLoanCategories.analyseLoans(theLoans);
552         theLoanCategories.produceTotals();
553         haveForeignCurrency |= theLoanCategories.haveForeignCurrency();
554 
555         /* Analyse the securities */
556         thePortfolios.analyseSecurities();
557         haveForeignCurrency |= thePortfolios.haveForeignCurrency();
558         haveActiveSecurities = thePortfolios.haveActiveSecurities();
559 
560         /* Analyse the Payees */
561         thePayees.produceTotals();
562 
563         /* Analyse the TransactionCategories */
564         theTransCategories.produceTotals();
565 
566         /* Analyse the TaxBasis */
567         theTaxBasis.produceTotals();
568 
569         /* Sort the transaction Tag list */
570         theTransTags.sortBuckets();
571     }
572 
573     /**
574      * Check totals.
575      */
576     public void checkTotals() {
577         /* Obtain Totals bucket */
578         final MoneyWiseXAnalysisDepositCategoryBucket myDepCat = theDepositCategories.getTotals();
579         final MoneyWiseXAnalysisCashCategoryBucket myCashCat = theCashCategories.getTotals();
580         final MoneyWiseXAnalysisLoanCategoryBucket myLoanCat = theLoanCategories.getTotals();
581         final MoneyWiseXAnalysisPortfolioBucket myPort = thePortfolios.getTotals();
582         final MoneyWiseXAnalysisPayeeBucket myPayee = thePayees.getTotals();
583         final MoneyWiseXAnalysisTransCategoryBucket myTrans = theTransCategories.getTotals();
584         final MoneyWiseXAnalysisTaxBasisBucket myTax = theTaxBasis.getTotals();
585 
586         /* Handle null data */
587         if (myDepCat == null) {
588             return;
589         }
590 
591         /* Access totals */
592         OceanusMoney myDepTotal = myDepCat.getValues().getMoneyValue(MoneyWiseXAnalysisAccountAttr.VALUEDELTA);
593         final OceanusMoney myCashTotal = myCashCat.getValues().getMoneyValue(MoneyWiseXAnalysisAccountAttr.VALUEDELTA);
594         final OceanusMoney myLoanTotal = myLoanCat.getValues().getMoneyValue(MoneyWiseXAnalysisAccountAttr.VALUEDELTA);
595         final OceanusMoney myPortTotal = myPort.getValues().getMoneyValue(MoneyWiseXAnalysisSecurityAttr.VALUEDELTA);
596         final OceanusMoney myPayTotal = myPayee.getValues().getMoneyValue(MoneyWiseXAnalysisPayeeAttr.PROFIT);
597         final OceanusMoney myEvtTotal = myTrans.getValues().getMoneyValue(MoneyWiseXAnalysisTransAttr.PROFIT);
598         final OceanusMoney myTaxTotal = myTax.getValues().getMoneyValue(MoneyWiseXAnalysisTaxBasisAttr.GROSS);
599 
600         /* Create a copy */
601         myDepTotal = new OceanusMoney(myDepTotal);
602 
603         /* Add sub-accounts */
604         myDepTotal.addAmount(myCashTotal);
605         myDepTotal.addAmount(myLoanTotal);
606         myDepTotal.addAmount(myPortTotal);
607 
608         /* Check identities */
609         if (!myDepTotal.equals(myPayTotal)) {
610             LOGGER.error("Payee total mismatch");
611         }
612         if (!myDepTotal.equals(myEvtTotal)) {
613             LOGGER.error("TransactionCategory total mismatch");
614         }
615         if (!myDepTotal.equals(myTaxTotal)) {
616             LOGGER.error("TaxBasis total mismatch");
617         }
618     }
619 }