1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.analyse;
18
19 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
21 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
22 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
24 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
25 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusUnits;
26 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
27 import io.github.tonywasher.joceanus.oceanus.profile.OceanusProfile;
28 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
29 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
30 import io.github.tonywasher.joceanus.metis.preference.MetisPreferenceManager;
31 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase;
32 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetType;
33 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
34 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCash;
35 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataSet;
36 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDeposit;
37 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan;
38 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
39 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio.MoneyWisePortfolioList;
40 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity;
41 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityHolding;
42 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityHolding.MoneyWiseSecurityHoldingMap;
43 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityPrice.MoneyWiseSecurityPriceDataMap;
44 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTax.MoneyWiseTaxCredit;
45 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
46 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory;
47 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransTag;
48 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction;
49 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction.MoneyWiseTransactionList;
50 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWisePayeeClass;
51 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWisePortfolioClass;
52 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityClass;
53 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransCategoryClass;
54 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseLogicException;
55 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysis;
56 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisAccountBucket;
57 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisCashBucket.MoneyWiseAnalysisCashBucketList;
58 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDataResource;
59 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisDepositBucket.MoneyWiseAnalysisDepositBucketList;
60 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisLoanBucket.MoneyWiseAnalysisLoanBucketList;
61 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPayeeBucket;
62 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPayeeBucket.MoneyWiseAnalysisPayeeBucketList;
63 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket;
64 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket.MoneyWiseAnalysisPortfolioBucketList;
65 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioCashBucket;
66 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket;
67 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisTaxBasisBucket.MoneyWiseAnalysisTaxBasisBucketList;
68 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisTransCategoryBucket;
69 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisTransCategoryBucket.MoneyWiseAnalysisTransCategoryBucketList;
70 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisTransTagBucket.MoneyWiseAnalysisTransTagBucketList;
71 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisTransactionHelper;
72 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityAttr;
73 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityValues;
74 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseCashType;
75 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
76
77 import java.util.Currency;
78 import java.util.Iterator;
79 import java.util.List;
80 import java.util.Objects;
81
82
83
84
85
86
87 public class MoneyWiseAnalysisTransAnalyser
88 implements MetisFieldItem {
89
90
91
92 private static final String ERROR_CATEGORY = "Unexpected Category Type: ";
93
94
95
96
97 private static final MetisFieldSet<MoneyWiseAnalysisTransAnalyser> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseAnalysisTransAnalyser.class);
98
99
100
101
102 static {
103 FIELD_DEFS.declareLocalField(MoneyWiseAnalysisDataResource.ANALYSIS_NAME, MoneyWiseAnalysisTransAnalyser::getAnalysis);
104 }
105
106
107
108
109 private static final OceanusMoney LIMIT_VALUE = OceanusMoney.getWholeUnits(3000);
110
111
112
113
114 private static final OceanusRate LIMIT_RATE = OceanusRate.getWholePercentage(5);
115
116
117
118
119 private final MoneyWiseSecurityHoldingMap theHoldingMap;
120
121
122
123
124 private final MoneyWiseSecurityPriceDataMap thePriceMap;
125
126
127
128
129 private final MoneyWiseAnalysis theAnalysis;
130
131
132
133
134 private final MoneyWiseAnalysisTransactionHelper theHelper;
135
136
137
138
139 private final MoneyWiseAnalysisDepositBucketList theDepositBuckets;
140
141
142
143
144 private final MoneyWiseAnalysisCashBucketList theCashBuckets;
145
146
147
148
149 private final MoneyWiseAnalysisLoanBucketList theLoanBuckets;
150
151
152
153
154 private final MoneyWiseAnalysisPortfolioBucketList thePortfolioBuckets;
155
156
157
158
159 private final MoneyWiseAnalysisPayeeBucketList thePayeeBuckets;
160
161
162
163
164 private final MoneyWiseAnalysisTransCategoryBucketList theCategoryBuckets;
165
166
167
168
169 private final MoneyWiseAnalysisTransTagBucketList theTagBuckets;
170
171
172
173
174 private final MoneyWiseAnalysisTaxBasisBucketList theTaxBasisBuckets;
175
176
177
178
179 private final MoneyWiseAnalysisPayeeBucket theTaxMan;
180
181
182
183
184 private final MoneyWiseAnalysisSecurityBucket theStatePension;
185
186
187
188
189 private final OceanusProfile theProfile;
190
191
192
193
194
195
196
197
198
199 public MoneyWiseAnalysisTransAnalyser(final OceanusProfile pTask,
200 final PrometheusEditSet pEditSet,
201 final MetisPreferenceManager pPreferenceMgr) throws OceanusException {
202
203 theProfile = pTask;
204 final OceanusProfile myTask = theProfile.startTask("analyseTransactions");
205 final MoneyWiseDataSet myDataSet = (MoneyWiseDataSet) pEditSet.getDataSet();
206
207
208 theHoldingMap = pEditSet.getDataList(MoneyWiseBasicDataType.PORTFOLIO, MoneyWisePortfolioList.class).getSecurityHoldingsMap();
209 thePriceMap = myDataSet.getSecurityPriceDataMap();
210
211
212 final MoneyWiseTransactionList myTrans = pEditSet.getDataList(MoneyWiseBasicDataType.TRANSACTION, MoneyWiseTransactionList.class);
213
214
215 myTask.startTask("Initialise");
216 theAnalysis = new MoneyWiseAnalysis(pEditSet, pPreferenceMgr);
217
218
219 theHelper = new MoneyWiseAnalysisTransactionHelper(myDataSet);
220 theAnalysis.addOpeningBalances(theHelper);
221
222
223 theDepositBuckets = theAnalysis.getDeposits();
224 theCashBuckets = theAnalysis.getCash();
225 theLoanBuckets = theAnalysis.getLoans();
226 thePortfolioBuckets = theAnalysis.getPortfolios();
227 thePayeeBuckets = theAnalysis.getPayees();
228 theCategoryBuckets = theAnalysis.getTransCategories();
229 theTagBuckets = theAnalysis.getTransactionTags();
230 theTaxBasisBuckets = theAnalysis.getTaxBasis();
231 theTaxMan = thePayeeBuckets.getBucket(MoneyWisePayeeClass.TAXMAN);
232
233
234 theStatePension = getStatePension(myDataSet);
235
236
237 myTask.startTask("Transactions");
238 final Iterator<MoneyWiseTransaction> myIterator = myTrans.iterator();
239 while (myIterator.hasNext()) {
240 final MoneyWiseTransaction myCurr = myIterator.next();
241
242
243 if (myCurr.isDeleted() || myCurr.isHeader()) {
244 continue;
245 }
246
247
248 myCurr.touchUnderlyingItems();
249
250
251 processTransaction(myCurr);
252 }
253
254
255 myTask.end();
256 }
257
258
259
260
261
262
263
264 private MoneyWiseAnalysisSecurityBucket getStatePension(final MoneyWiseDataSet pData) {
265
266 final MoneyWisePortfolio myPensionPort = pData.getPortfolios().getSingularClass(MoneyWisePortfolioClass.PENSION);
267 final MoneyWiseSecurity myStatePension = pData.getSecurities().getSingularClass(MoneyWiseSecurityClass.STATEPENSION);
268
269
270 if (myPensionPort != null
271 && myStatePension != null) {
272 final MoneyWiseSecurityHolding myHolding = pData.getPortfolios().getSecurityHoldingsMap().declareHolding(myPensionPort, myStatePension);
273 return thePortfolioBuckets.getBucket(myHolding);
274 }
275
276
277 return null;
278 }
279
280 @Override
281 public MetisFieldSet<MoneyWiseAnalysisTransAnalyser> getDataFieldSet() {
282 return FIELD_DEFS;
283 }
284
285 @Override
286 public String formatObject(final OceanusDataFormatter pFormatter) {
287 return FIELD_DEFS.getName();
288 }
289
290
291
292
293
294
295 public MoneyWiseAnalysis getAnalysis() {
296 return theAnalysis;
297 }
298
299
300
301
302
303
304 public void postProcessAnalysis() throws OceanusException {
305
306 final OceanusProfile myTask = theProfile.startTask("postProcessAnalysis");
307 myTask.startTask("markActiveAccounts");
308
309
310 theDepositBuckets.markActiveAccounts();
311 theCashBuckets.markActiveAccounts();
312 theLoanBuckets.markActiveAccounts();
313
314
315 thePortfolioBuckets.markActiveSecurities();
316
317
318 myTask.end();
319 }
320
321
322
323
324
325
326
327 private void processTransaction(final MoneyWiseTransaction pTrans) throws OceanusException {
328
329 theHelper.setTransaction(pTrans);
330
331
332 final MoneyWiseTransAsset myDebitAsset = theHelper.getDebitAsset();
333 final MoneyWiseTransAsset myCreditAsset = theHelper.getCreditAsset();
334 final MoneyWiseTaxCredit myYear = pTrans.getTaxYear();
335
336
337 final List<MoneyWiseTransTag> myTags = pTrans.getTransactionTags();
338 if (myTags != null) {
339
340 theTagBuckets.processTransaction(pTrans, myTags.iterator());
341 }
342
343
344 if (myDebitAsset instanceof MoneyWiseSecurityHolding) {
345
346 processDebitSecurityTransaction((MoneyWiseSecurityHolding) myDebitAsset, myCreditAsset);
347
348
349 } else if (myCreditAsset instanceof MoneyWiseSecurityHolding) {
350
351 processCreditSecurityTransaction(myDebitAsset, (MoneyWiseSecurityHolding) myCreditAsset);
352
353
354 } else if (myDebitAsset instanceof MoneyWisePortfolio
355 && myCreditAsset instanceof MoneyWisePortfolio
356 && pTrans.getCategoryClass() == MoneyWiseTransCategoryClass.PORTFOLIOXFER
357 && !myDebitAsset.equals(myCreditAsset)) {
358
359 processPortfolioXfer((MoneyWisePortfolio) myDebitAsset, (MoneyWisePortfolio) myCreditAsset);
360
361
362 } else if (myDebitAsset instanceof MoneyWiseAssetBase
363 && myCreditAsset instanceof MoneyWiseAssetBase) {
364
365 MoneyWiseAssetBase myDebit = (MoneyWiseAssetBase) myDebitAsset;
366 MoneyWiseAssetBase myCredit = (MoneyWiseAssetBase) myCreditAsset;
367 MoneyWiseAssetBase myChild = null;
368 final OceanusMoney myAmount = pTrans.getAmount();
369 MoneyWiseTransCategory myCat = pTrans.getCategory();
370
371
372 switch (myCat.getCategoryTypeClass()) {
373 case INTEREST:
374 case LOYALTYBONUS:
375
376 myCat = myDebit.getDetailedCategory(myCat, myYear);
377
378
379 myChild = myDebit.equals(myCredit)
380 ? null
381 : myDebit;
382 myDebit = myDebit.getParent();
383 break;
384 case LOANINTERESTEARNED:
385 case CASHBACK:
386
387 myDebit = myDebit.getParent();
388 break;
389 case RENTALINCOME:
390 case ROOMRENTALINCOME:
391
392 myChild = myDebit.equals(myCredit)
393 ? null
394 : myDebit;
395 myDebit = myCredit.getParent();
396 break;
397 case WRITEOFF:
398 case LOANINTERESTCHARGED:
399
400 myCredit = myCredit.getParent();
401 break;
402 default:
403 break;
404 }
405
406
407 if (myDebit instanceof MoneyWiseCash
408 && myDebit.getAssetType() == MoneyWiseAssetType.AUTOEXPENSE) {
409
410 final MoneyWiseCash myCash = (MoneyWiseCash) myDebit;
411 final MoneyWiseTransCategory myAuto = myCash.getAutoExpense();
412 myDebit = myCash.getAutoPayee();
413 myDebit.touchItem(pTrans);
414
415
416 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myDebit);
417 myPayee.subtractExpense(theHelper, myAmount);
418
419
420 final MoneyWiseAnalysisTransCategoryBucket myCatBucket = theCategoryBuckets.getBucket(myAuto);
421 myCatBucket.subtractExpense(theHelper, myAmount);
422 theTaxBasisBuckets.adjustAutoExpense(theHelper, false);
423
424
425 } else if (MoneyWiseAssetType.PAYEE.equals(myDebit.getAssetType())) {
426 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myDebit);
427 myPayee.adjustForDebit(theHelper);
428
429
430 } else {
431 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket(myDebit);
432 myBucket.adjustForDebit(theHelper);
433 }
434
435
436 if (myCredit instanceof MoneyWiseCash
437 && myCredit.getAssetType() == MoneyWiseAssetType.AUTOEXPENSE) {
438
439 final MoneyWiseCash myCash = (MoneyWiseCash) myCredit;
440 final MoneyWiseTransCategory myAuto = myCash.getAutoExpense();
441 myCredit = myCash.getAutoPayee();
442 myCredit.touchItem(pTrans);
443
444
445 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myCredit);
446 myPayee.addExpense(theHelper, myAmount);
447
448
449 final MoneyWiseAnalysisTransCategoryBucket myCatBucket = theCategoryBuckets.getBucket(myAuto);
450 myCatBucket.addExpense(theHelper, myAmount);
451 theTaxBasisBuckets.adjustAutoExpense(theHelper, true);
452
453
454 } else if (MoneyWiseAssetType.PAYEE.equals(myCredit.getAssetType())) {
455 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myCredit);
456 myPayee.adjustForCredit(theHelper);
457
458
459 } else {
460 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket(myCredit);
461 myBucket.adjustForCredit(theHelper);
462 }
463
464
465 if (myChild != null) {
466
467 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket(myChild);
468 myBucket.registerTransaction(pTrans);
469 }
470
471
472 theTaxMan.adjustForTaxPayments(theHelper);
473 theStatePension.adjustForNIPayments(theHelper);
474
475
476 if (!myCat.isTransfer()) {
477
478 theCategoryBuckets.adjustCategories(theHelper, myCat);
479 }
480
481
482 } else {
483 throw new MoneyWiseLogicException("Invalid Asset Pair: "
484 + pTrans.getAccount().getAssetType()
485 + " "
486 + pTrans.getDirection()
487 + " "
488 + pTrans.getPartner().getAssetType());
489 }
490 }
491
492
493
494
495
496
497
498
499 private void processDebitSecurityTransaction(final MoneyWiseSecurityHolding pDebit,
500 final MoneyWiseTransAsset pCredit) throws OceanusException {
501
502 if (pCredit instanceof MoneyWiseSecurityHolding) {
503
504 processDebitCreditSecurityTransaction(pDebit, (MoneyWiseSecurityHolding) pCredit);
505 return;
506 }
507
508
509 final MoneyWiseTransCategory myCat = theHelper.getCategory();
510 switch (myCat.getCategoryTypeClass()) {
511
512 case STOCKRIGHTSISSUE:
513 processTransferOut(pDebit, (MoneyWiseAssetBase) pCredit);
514 break;
515
516 case DIVIDEND:
517 processDividend(pDebit, pCredit);
518 break;
519 case PORTFOLIOXFER:
520 processPortfolioXfer(pDebit, (MoneyWisePortfolio) pCredit);
521 break;
522
523 case TRANSFER:
524 case SECURITYCLOSURE:
525 case EXPENSE:
526 case INHERITED:
527 case OTHERINCOME:
528 if (pDebit.getSecurity().isSecurityClass(MoneyWiseSecurityClass.LIFEBOND)) {
529 processChargeableGain(pDebit, (MoneyWiseAssetBase) pCredit);
530 } else {
531 processTransferOut(pDebit, (MoneyWiseAssetBase) pCredit);
532 }
533 break;
534
535 default:
536 throw new MoneyWiseLogicException(ERROR_CATEGORY
537 + myCat.getCategoryTypeClass());
538 }
539 }
540
541
542
543
544
545
546
547
548 private void processDebitCreditSecurityTransaction(final MoneyWiseSecurityHolding pDebit,
549 final MoneyWiseSecurityHolding pCredit) throws OceanusException {
550
551 final MoneyWiseTransCategory myCat = theHelper.getCategory();
552 switch (myCat.getCategoryTypeClass()) {
553
554 case STOCKSPLIT:
555 case UNITSADJUST:
556 processUnitsAdjust(pDebit);
557 break;
558
559 case STOCKDEMERGER:
560 processStockDeMerger(pDebit, pCredit);
561 break;
562
563 case SECURITYREPLACE:
564 case STOCKTAKEOVER:
565 processStockTakeover(pDebit, pCredit);
566 break;
567
568 case DIVIDEND:
569 processDividend(pDebit, pCredit);
570 break;
571
572 case TRANSFER:
573 case EXPENSE:
574 case INHERITED:
575 case OTHERINCOME:
576 processStockXchange(pDebit, pCredit);
577 break;
578
579 default:
580 throw new MoneyWiseLogicException(ERROR_CATEGORY
581 + myCat.getCategoryTypeClass());
582 }
583 }
584
585
586
587
588
589
590
591
592 private void processCreditSecurityTransaction(final MoneyWiseTransAsset pDebit,
593 final MoneyWiseSecurityHolding pCredit) throws OceanusException {
594
595 if (!(pDebit instanceof MoneyWiseAssetBase)) {
596 throw new MoneyWiseLogicException("Invalid Debit Asset: "
597 + pDebit.getAssetType());
598 }
599 final MoneyWiseAssetBase myDebit = (MoneyWiseAssetBase) pDebit;
600
601
602 final MoneyWiseTransCategory myCat = theHelper.getCategory();
603 switch (myCat.getCategoryTypeClass()) {
604
605 case STOCKRIGHTSISSUE:
606 case TRANSFER:
607 case EXPENSE:
608 case INHERITED:
609 case OTHERINCOME:
610 case PENSIONCONTRIB:
611 processTransferIn(myDebit, pCredit);
612 break;
613
614 default:
615 throw new MoneyWiseLogicException(ERROR_CATEGORY
616 + myCat.getCategoryTypeClass());
617 }
618 }
619
620
621
622
623
624
625
626
627
628 private void processPortfolioXfer(final MoneyWisePortfolio pSource,
629 final MoneyWisePortfolio pTarget) {
630
631 final MoneyWiseAnalysisPortfolioBucket mySource = thePortfolioBuckets.getBucket(pSource);
632 final MoneyWiseAnalysisPortfolioBucket myTarget = thePortfolioBuckets.getBucket(pTarget);
633
634
635 final MoneyWiseAnalysisPortfolioCashBucket mySourceCash = mySource.getPortfolioCash();
636 if (mySourceCash.isActive()) {
637
638 final MoneyWiseAnalysisPortfolioCashBucket myTargetCash = myTarget.getPortfolioCash();
639 myTargetCash.adjustForXfer(mySourceCash, theHelper);
640 }
641
642
643 final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = mySource.securityIterator();
644 while (myIterator.hasNext()) {
645 final MoneyWiseAnalysisSecurityBucket myBucket = myIterator.next();
646
647
648 if (myBucket.isActive()) {
649
650 final MoneyWiseSecurityHolding myTargetHolding = theHoldingMap.declareHolding(pTarget, myBucket.getSecurity());
651 final MoneyWiseAnalysisSecurityBucket myTargetBucket = myTarget.getSecurityBucket(myTargetHolding);
652 theHelper.setSecurity(myBucket.getSecurity());
653
654
655 processPortfolioXfer(myBucket, myTargetBucket);
656 }
657 }
658
659
660 }
661
662
663
664
665
666
667
668 private void processPortfolioXfer(final MoneyWiseAnalysisSecurityBucket pSource,
669 final MoneyWiseAnalysisSecurityBucket pTarget) {
670
671 MoneyWiseAnalysisSecurityValues mySourceValues = pSource.getValues();
672 OceanusUnits myUnits = mySourceValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
673 OceanusMoney myCost = mySourceValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
674 OceanusMoney myGains = mySourceValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS);
675 OceanusMoney myInvested = mySourceValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED);
676 OceanusMoney myForeignInvested = mySourceValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED);
677 final boolean isForeign = pSource.isForeignCurrency();
678
679
680 final OceanusPrice myPrice = thePriceMap.getPriceForDate(pSource.getSecurity(), theHelper.getDate());
681 OceanusMoney myStockValue = myUnits.valueAtPrice(myPrice);
682 OceanusMoney myForeignValue = null;
683 OceanusRatio myRate = null;
684
685
686 if (isForeign) {
687
688 myRate = theHelper.getDebitExchangeRate();
689 myForeignValue = myStockValue;
690 myStockValue = myStockValue.convertCurrency(theAnalysis.getCurrency().getCurrency(), myRate);
691 }
692
693
694 OceanusMoney myProfit = new OceanusMoney(myStockValue);
695 myProfit.subtractAmount(myCost);
696 pSource.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
697 myProfit = new OceanusMoney(myProfit);
698 myProfit.negate();
699 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
700
701
702 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myUnits);
703 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myCost);
704 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myInvested);
705 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS, myGains);
706 final MoneyWiseAnalysisSecurityValues myTargetValues = pTarget.registerTransaction(theHelper);
707 myTargetValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myPrice);
708 myTargetValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myStockValue);
709 myTargetValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myCost);
710 if (isForeign) {
711 myTargetValues.setValue(MoneyWiseAnalysisSecurityAttr.FOREIGNVALUE, myForeignValue);
712 myTargetValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myRate);
713 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myForeignInvested);
714 }
715
716
717 myUnits = new OceanusUnits(myUnits);
718 myUnits.negate();
719 pSource.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myUnits);
720 myCost = new OceanusMoney(myCost);
721 myCost.negate();
722 pSource.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myCost);
723 myCost.negate();
724 myInvested = new OceanusMoney(myInvested);
725 myInvested.negate();
726 pSource.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myInvested);
727 myGains = new OceanusMoney(myGains);
728 myGains.negate();
729 pSource.adjustCounter(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS, myGains);
730 mySourceValues = pSource.registerTransaction(theHelper);
731 mySourceValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myPrice);
732 mySourceValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myStockValue);
733 mySourceValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myCost);
734 if (isForeign) {
735 mySourceValues.setValue(MoneyWiseAnalysisSecurityAttr.FOREIGNVALUE, myForeignValue);
736 mySourceValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myRate);
737 myForeignInvested = new OceanusMoney(myForeignInvested);
738 myForeignInvested.negate();
739 pTarget.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myForeignInvested);
740 }
741 }
742
743
744
745
746
747
748
749
750
751 private void processPortfolioXfer(final MoneyWiseSecurityHolding pSource,
752 final MoneyWisePortfolio pTarget) {
753
754 final MoneyWiseAnalysisPortfolioBucket mySource = thePortfolioBuckets.getBucket(pSource.getPortfolio());
755 final MoneyWiseAnalysisPortfolioBucket myTarget = thePortfolioBuckets.getBucket(pTarget);
756
757
758 final MoneyWiseAnalysisSecurityBucket myBucket = mySource.getSecurityBucket(pSource);
759
760
761 if (myBucket.isActive()) {
762
763 final MoneyWiseSecurityHolding myTargetHolding = theHoldingMap.declareHolding(pTarget, myBucket.getSecurity());
764 final MoneyWiseAnalysisSecurityBucket myTargetBucket = myTarget.getSecurityBucket(myTargetHolding);
765
766
767 processPortfolioXfer(myBucket, myTargetBucket);
768 }
769
770
771 }
772
773
774
775
776
777
778
779
780 private void processUnitsAdjust(final MoneyWiseSecurityHolding pHolding) {
781
782 final OceanusUnits myDelta = theHelper.getAccountDeltaUnits();
783
784
785 final MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pHolding);
786 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDelta);
787
788
789 myAsset.registerTransaction(theHelper);
790
791
792 }
793
794
795
796
797
798
799
800
801
802 private void processTransferIn(final MoneyWiseAssetBase pDebit,
803 final MoneyWiseSecurityHolding pCredit) {
804
805 final MoneyWiseTransCategory myCat = theHelper.getCategory();
806
807
808 processCreditXferIn(pCredit);
809
810
811 theTaxMan.adjustForTaxPayments(theHelper);
812
813
814 switch (pDebit.getAssetType()) {
815 case PAYEE:
816 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(pDebit);
817 myPayee.adjustForDebit(theHelper);
818 break;
819 default:
820 final MoneyWiseAnalysisAccountBucket<?> myAccount = getAccountBucket(pDebit);
821 myAccount.adjustForDebit(theHelper);
822 break;
823 }
824
825
826 if (!myCat.isTransfer()) {
827
828 theCategoryBuckets.adjustCategories(theHelper, myCat);
829 }
830 }
831
832
833
834
835
836
837 private void processCreditXferIn(final MoneyWiseSecurityHolding pHolding) {
838
839 OceanusMoney myAmount = theHelper.getCreditAmount();
840 final OceanusRatio myExchangeRate = theHelper.getCreditExchangeRate();
841 final MoneyWiseSecurity mySecurity = pHolding.getSecurity();
842
843
844 final MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pHolding);
845 final boolean isForeign = myAsset.isForeignCurrency();
846
847
848 if (isForeign) {
849
850 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myAmount);
851
852
853 myAmount = theHelper.getLocalAmount();
854 }
855
856
857 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myAmount);
858 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myAmount);
859
860
861 final MoneyWiseSecurityClass mySecClass = mySecurity.getCategoryClass();
862 OceanusUnits myDeltaUnits = theHelper.getCreditUnits();
863 OceanusUnits myUnits = myAsset.getValues().getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
864 if (mySecClass.isAutoUnits() && myUnits.isZero()) {
865 myDeltaUnits = OceanusUnits.getWholeUnits(mySecClass.getAutoUnits());
866 }
867
868
869 if (myDeltaUnits != null) {
870
871 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDeltaUnits);
872 }
873
874
875 myAsset.adjustForNIPayments(theHelper);
876
877
878 final OceanusPrice myPrice = thePriceMap.getPriceForDate(mySecurity, theHelper.getDate());
879
880
881 myUnits = myAsset.getValues().getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
882 OceanusMoney myValue = myUnits.valueAtPrice(myPrice);
883
884
885 if (isForeign) {
886
887 myValue = myValue.convertCurrency(theAnalysis.getCurrency().getCurrency(), myExchangeRate);
888 }
889
890
891 final MoneyWiseAnalysisSecurityValues myValues = myAsset.registerTransaction(theHelper);
892 myValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myPrice);
893 myValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myValue);
894 myValues.setValue(MoneyWiseAnalysisSecurityAttr.CASHINVESTED, myAmount);
895 if (isForeign) {
896 myValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myExchangeRate);
897 }
898 }
899
900
901
902
903
904
905
906
907
908
909 private void processDividend(final MoneyWiseSecurityHolding pHolding,
910 final MoneyWiseTransAsset pCredit) {
911
912 final MoneyWisePortfolio myPortfolio = pHolding.getPortfolio();
913 final MoneyWiseSecurity mySecurity = pHolding.getSecurity();
914 OceanusMoney myAmount = theHelper.getDebitAmount();
915 final OceanusMoney myTaxCredit = theHelper.getTaxCredit();
916 final OceanusUnits myDeltaUnits = theHelper.getAccountDeltaUnits();
917 final MoneyWiseTaxCredit myYear = theHelper.getTransaction().getTaxYear();
918
919
920 MoneyWiseTransCategory myCat = myPortfolio.getDetailedCategory(theHelper.getCategory(), myYear);
921 myCat = mySecurity.getDetailedCategory(myCat, myYear);
922
923
924 final MoneyWiseAssetBase myDebit = mySecurity.getParent();
925
926
927 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myDebit);
928 myPayee.adjustForDebit(theHelper);
929
930
931 final MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pHolding);
932 final boolean isForeign = myAsset.isForeignCurrency();
933 final boolean isReInvest = pCredit instanceof MoneyWiseSecurityHolding;
934
935
936 if (isForeign) {
937
938 if (isReInvest) {
939
940 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myAmount);
941 myAsset.getValues().setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, theHelper.getCreditExchangeRate());
942 }
943
944
945 myAmount = theHelper.getLocalAmount();
946 }
947
948
949 if (isReInvest) {
950
951 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myAmount);
952
953
954 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myAmount);
955
956
957 if (myDeltaUnits != null) {
958
959 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDeltaUnits);
960 }
961
962
963 if (myTaxCredit != null) {
964
965 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.DIVIDEND, myTaxCredit);
966 }
967
968
969 } else {
970
971 final OceanusMoney myAdjust = new OceanusMoney(myAmount);
972
973
974 if (myTaxCredit != null) {
975 myAdjust.addAmount(myTaxCredit);
976 }
977
978
979 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.DIVIDEND, myAdjust);
980
981
982 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket((MoneyWiseAssetBase) pCredit);
983 myBucket.adjustForCredit(theHelper);
984 }
985
986
987 myAsset.registerTransaction(theHelper);
988
989
990 theTaxMan.adjustForTaxPayments(theHelper);
991
992
993 theCategoryBuckets.adjustCategories(theHelper, myCat);
994 }
995
996
997
998
999
1000
1001
1002
1003
1004 private void processTransferOut(final MoneyWiseSecurityHolding pHolding,
1005 final MoneyWiseAssetBase pCredit) {
1006
1007 final MoneyWiseTransCategory myCat = theHelper.getCategory();
1008
1009
1010 processDebitXferOut(pHolding);
1011
1012
1013 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket(pCredit);
1014 myBucket.adjustForCredit(theHelper);
1015
1016
1017 if (!myCat.isTransfer()) {
1018
1019 theCategoryBuckets.adjustCategories(theHelper, myCat);
1020 }
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030 private void processDebitXferOut(final MoneyWiseSecurityHolding pHolding) {
1031
1032 final MoneyWiseSecurity myDebit = pHolding.getSecurity();
1033 OceanusMoney myAmount = theHelper.getDebitAmount();
1034 boolean isLargeCash = false;
1035
1036
1037 final MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pHolding);
1038 MoneyWiseAnalysisSecurityValues myValues = myAsset.getValues();
1039 final OceanusRatio myXchangeRate = theHelper.getDebitExchangeRate();
1040 final boolean isForeign = myAsset.isForeignCurrency();
1041
1042
1043 if (isForeign) {
1044
1045 final OceanusMoney myDelta = new OceanusMoney(myAmount);
1046 myDelta.negate();
1047 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myDelta);
1048
1049
1050 myAmount = theHelper.getLocalAmount();
1051 }
1052
1053
1054 final OceanusMoney myDelta = new OceanusMoney(myAmount);
1055 myDelta.negate();
1056 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myDelta);
1057
1058
1059 final OceanusPrice myPrice = thePriceMap.getPriceForDate(myDebit, theHelper.getDate());
1060
1061
1062 OceanusUnits myUnits = Objects.requireNonNull(myValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS));
1063 OceanusMoney myAllowedCost = new OceanusMoney(myAmount);
1064 final OceanusMoney myCost = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
1065 OceanusRatio myCostDilution = null;
1066 OceanusMoney myConsideration = null;
1067
1068
1069 OceanusUnits myDeltaUnits = theHelper.getCategoryClass().isSecurityClosure()
1070 ? myUnits
1071 : theHelper.getDebitUnits();
1072 final boolean isCapitalDistribution = myDeltaUnits == null;
1073
1074
1075 if (!isCapitalDistribution) {
1076
1077 myAllowedCost = myCost.valueAtWeight(myDeltaUnits, myUnits);
1078
1079
1080 myDeltaUnits = new OceanusUnits(myDeltaUnits);
1081 myDeltaUnits.negate();
1082
1083
1084 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDeltaUnits);
1085 final OceanusUnits myNewUnits = myValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1086
1087
1088 myCostDilution = new OceanusRatio(myNewUnits, myUnits);
1089 myUnits = myNewUnits;
1090 }
1091
1092
1093 OceanusMoney myValue = myUnits.valueAtPrice(myPrice);
1094
1095
1096 if (isForeign) {
1097
1098 myValue = myValue.convertCurrency(theAnalysis.getCurrency().getCurrency(), myXchangeRate);
1099 }
1100
1101
1102 if (isCapitalDistribution) {
1103
1104 final OceanusMoney myPortion = myValue.valueAtRate(LIMIT_RATE);
1105 isLargeCash = (myAmount.compareTo(LIMIT_VALUE) > 0)
1106 && (myAmount.compareTo(myPortion) > 0);
1107
1108
1109 if (isLargeCash) {
1110
1111 myConsideration = new OceanusMoney(myAmount);
1112 myConsideration.addAmount(myValue);
1113
1114
1115 myAllowedCost = myCost.valueAtWeight(myAmount, myConsideration);
1116
1117
1118 myCostDilution = new OceanusRatio(myValue, myConsideration);
1119
1120
1121 } else {
1122
1123 myAllowedCost = myAmount.compareTo(myCost) > 0
1124 ? new OceanusMoney(myCost)
1125 : new OceanusMoney(myAmount);
1126 }
1127 }
1128
1129
1130 final OceanusMoney myDeltaCost = new OceanusMoney(myAllowedCost);
1131 myDeltaCost.negate();
1132
1133
1134 if (myDeltaCost.isNonZero()) {
1135
1136 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1137 }
1138
1139
1140 final OceanusMoney myCapitalGain = new OceanusMoney(myAmount);
1141 myCapitalGain.addAmount(myDeltaCost);
1142
1143
1144 if (myCapitalGain.isNonZero()) {
1145
1146 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS, myCapitalGain);
1147
1148
1149 theCategoryBuckets.adjustStandardGain(theHelper, pHolding, myCapitalGain);
1150 }
1151
1152
1153 myValues = myAsset.registerTransaction(theHelper);
1154
1155
1156 myValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myPrice);
1157 myValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myValue);
1158 myValues.setValue(MoneyWiseAnalysisSecurityAttr.RETURNEDCASH, myAmount);
1159 myValues.setValue(MoneyWiseAnalysisSecurityAttr.ALLOWEDCOST, myAllowedCost);
1160 if (myCostDilution != null) {
1161 myValues.setValue(MoneyWiseAnalysisSecurityAttr.COSTDILUTION, myCostDilution);
1162 }
1163 if (myConsideration != null) {
1164 myValues.setValue(MoneyWiseAnalysisSecurityAttr.CONSIDERATION, myConsideration);
1165 }
1166 if (myCapitalGain.isNonZero()) {
1167 myValues.setValue(MoneyWiseAnalysisSecurityAttr.CAPITALGAIN, myCapitalGain);
1168 }
1169 if (isForeign) {
1170 myValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myXchangeRate);
1171 }
1172 if (isCapitalDistribution) {
1173 myValues.setValue(MoneyWiseAnalysisSecurityAttr.CASHTYPE, isLargeCash
1174 ? MoneyWiseCashType.LARGECASH
1175 : MoneyWiseCashType.SMALLCASH);
1176 }
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187 private void processStockXchange(final MoneyWiseSecurityHolding pDebit,
1188 final MoneyWiseSecurityHolding pCredit) {
1189
1190 processDebitXferOut(pDebit);
1191
1192
1193 processCreditXferIn(pCredit);
1194 }
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 private void processChargeableGain(final MoneyWiseSecurityHolding pHolding,
1205 final MoneyWiseAssetBase pCredit) {
1206
1207 final MoneyWiseSecurity myDebit = pHolding.getSecurity();
1208 OceanusMoney myAmount = theHelper.getDebitAmount();
1209 OceanusUnits myDeltaUnits = theHelper.getDebitUnits();
1210
1211
1212 final MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pHolding);
1213 final MoneyWiseAnalysisSecurityValues myValues = myAsset.getValues();
1214
1215
1216 if (Boolean.TRUE.equals(myAsset.isForeignCurrency())) {
1217
1218 final OceanusMoney myDelta = new OceanusMoney(myAmount);
1219 myDelta.negate();
1220 myValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, theHelper.getDebitExchangeRate());
1221 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myDelta);
1222
1223
1224 myAmount = theHelper.getLocalAmount();
1225 }
1226
1227
1228 final OceanusMoney myDelta = new OceanusMoney(myAmount);
1229 myDelta.negate();
1230 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myDelta);
1231
1232
1233 OceanusMoney myReduction = new OceanusMoney(myAmount);
1234 final OceanusMoney myCost = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
1235
1236
1237 if (myDeltaUnits != null) {
1238
1239 final OceanusUnits myUnits = myValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1240 myReduction = myCost.valueAtWeight(myDeltaUnits, myUnits);
1241
1242
1243 myDeltaUnits = new OceanusUnits(myDeltaUnits);
1244 myDeltaUnits.negate();
1245
1246
1247 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDeltaUnits);
1248 }
1249
1250
1251 if (myReduction.compareTo(myCost) > 0) {
1252
1253 myReduction = new OceanusMoney(myCost);
1254 }
1255
1256
1257 final OceanusMoney myDeltaCost = new OceanusMoney(myReduction);
1258 myDeltaCost.negate();
1259
1260
1261 if (myDeltaCost.isNonZero()) {
1262
1263 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1264 }
1265
1266
1267 final OceanusMoney myDeltaGains = new OceanusMoney(myAmount);
1268 myDeltaGains.addAmount(myDeltaCost);
1269
1270
1271 if (myDeltaGains.isNonZero()) {
1272
1273 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS, myDeltaGains);
1274 }
1275
1276
1277 myAsset.registerTransaction(theHelper);
1278
1279
1280 final MoneyWiseAssetBase myParent = myDebit.getParent();
1281
1282
1283 final MoneyWiseAnalysisPayeeBucket myPayee = thePayeeBuckets.getBucket(myParent);
1284 myPayee.adjustForTaxCredit(theHelper);
1285
1286
1287 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket(pCredit);
1288 myBucket.adjustForCredit(theHelper);
1289
1290
1291 theCategoryBuckets.adjustChargeableGain(theHelper, myReduction);
1292
1293
1294 theTaxMan.adjustForTaxPayments(theHelper);
1295
1296
1297 theTaxBasisBuckets.recordChargeableGain(theHelper.getTransaction(), myDeltaGains);
1298 }
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308 private void processStockDeMerger(final MoneyWiseSecurityHolding pDebit,
1309 final MoneyWiseSecurityHolding pCredit) {
1310
1311 MoneyWiseAnalysisSecurityBucket myAsset = thePortfolioBuckets.getBucket(pDebit);
1312 MoneyWiseAnalysisSecurityValues myValues = myAsset.getValues();
1313 final OceanusRatio myDebitRate = theHelper.getDebitExchangeRate();
1314
1315
1316 final OceanusMoney myCost = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
1317 final OceanusRatio myDilution = theHelper.getDilution();
1318 final OceanusUnits myDeltaUnits = theHelper.getAccountDeltaUnits();
1319
1320
1321 if (myDeltaUnits != null) {
1322
1323 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDeltaUnits);
1324 }
1325
1326
1327 final OceanusMoney myNewCost = myCost.getDilutedMoney(myDilution);
1328 final OceanusRatio myCostDilution = new OceanusRatio(myNewCost, myCost);
1329
1330
1331 OceanusMoney myDeltaCost = new OceanusMoney(myNewCost);
1332 myDeltaCost.subtractAmount(myCost);
1333
1334
1335 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1336 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myDeltaCost);
1337 final boolean isForeignDebit = myAsset.isForeignCurrency();
1338 if (isForeignDebit) {
1339 final OceanusMoney myInvested = myDeltaCost.convertCurrency(myAsset.getCurrency().getCurrency(), myDebitRate);
1340 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myInvested);
1341 }
1342
1343
1344 myValues = myAsset.registerTransaction(theHelper);
1345
1346
1347 myAsset = thePortfolioBuckets.getBucket(pCredit);
1348
1349
1350 myDeltaCost = new OceanusMoney(myDeltaCost);
1351 myDeltaCost.negate();
1352
1353
1354 myValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myDeltaCost);
1355 myValues.setValue(MoneyWiseAnalysisSecurityAttr.COSTDILUTION, myCostDilution);
1356 if (isForeignDebit) {
1357 myValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myDebitRate);
1358 }
1359
1360
1361 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1362 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myDeltaCost);
1363 final boolean isForeignCredit = myAsset.isForeignCurrency();
1364 final OceanusRatio myCreditRate = theHelper.getCreditExchangeRate();
1365 if (isForeignCredit) {
1366 final OceanusMoney myInvested = myDeltaCost.convertCurrency(myAsset.getCurrency().getCurrency(), myCreditRate);
1367 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myInvested);
1368 }
1369
1370
1371 final OceanusDate myDate = theHelper.getDate();
1372 final OceanusPrice myCreditPrice = thePriceMap.getPriceForDate(myAsset.getSecurity(), myDate);
1373 final Currency myCurrency = theAnalysis.getCurrency().getCurrency();
1374
1375
1376 final OceanusUnits myCreditUnits = theHelper.getPartnerDeltaUnits();
1377 OceanusMoney myCreditXferValue = myCreditUnits.valueAtPrice(myCreditPrice);
1378 if (isForeignCredit) {
1379 myCreditXferValue = myCreditXferValue.convertCurrency(myCurrency, myCreditRate);
1380 }
1381
1382
1383 myAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myCreditUnits);
1384
1385
1386 myValues = myAsset.registerTransaction(theHelper);
1387
1388
1389 myValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myDeltaCost);
1390 myValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myCreditPrice);
1391 myValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDVALUE, myCreditXferValue);
1392 if (isForeignCredit) {
1393 myValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myCreditRate);
1394 }
1395
1396
1397 }
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408 private void processStockTakeover(final MoneyWiseSecurityHolding pDebit,
1409 final MoneyWiseSecurityHolding pCredit) {
1410 final OceanusMoney myAmount = theHelper.getReturnedCash();
1411 final MoneyWiseTransAsset myReturnedCashAct = theHelper.getReturnedCashAccount();
1412
1413
1414 if (myReturnedCashAct != null
1415 && myAmount.isNonZero()) {
1416
1417 processStockAndCashTakeOver(pDebit, pCredit);
1418 } else {
1419
1420 processStockOnlyTakeOver(pDebit, pCredit);
1421 }
1422 }
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432 private void processStockOnlyTakeOver(final MoneyWiseSecurityHolding pDebit,
1433 final MoneyWiseSecurityHolding pCredit) {
1434
1435 final MoneyWiseSecurity myCredit = pCredit.getSecurity();
1436 final MoneyWiseSecurity myDebit = pDebit.getSecurity();
1437
1438
1439 final MoneyWiseAnalysisSecurityBucket myDebitAsset = thePortfolioBuckets.getBucket(pDebit);
1440 MoneyWiseAnalysisSecurityValues myDebitValues = myDebitAsset.getValues();
1441 final MoneyWiseAnalysisSecurityBucket myCreditAsset = thePortfolioBuckets.getBucket(pCredit);
1442 final OceanusDate myDate = theHelper.getDate();
1443
1444
1445 final OceanusPrice myCreditPrice = thePriceMap.getPriceForDate(myCredit, myDate);
1446 final OceanusPrice myDebitPrice = thePriceMap.getPriceForDate(myDebit, myDate);
1447 final OceanusRatio myDebitRate = theHelper.getDebitExchangeRate();
1448 final OceanusRatio myCreditRate = theHelper.getCreditExchangeRate();
1449 final Currency myCurrency = theAnalysis.getCurrency().getCurrency();
1450
1451
1452 OceanusUnits myCreditUnits = theHelper.getPartnerDeltaUnits();
1453 OceanusMoney myCreditXferValue = myCreditUnits.valueAtPrice(myCreditPrice);
1454 OceanusUnits myDebitUnits = myDebitValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1455 OceanusMoney myDebitValue = myDebitUnits.valueAtPrice(myDebitPrice);
1456 OceanusMoney myInvested = myDebitValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED);
1457
1458
1459 final boolean isForeignDebit = myDebitAsset.isForeignCurrency();
1460 if (isForeignDebit) {
1461 myDebitValue = myDebitValue.convertCurrency(myCurrency, myDebitRate);
1462 }
1463
1464
1465 final boolean isForeignCredit = myCreditAsset.isForeignCurrency();
1466 if (isForeignCredit) {
1467 myCreditXferValue = myCreditXferValue.convertCurrency(myCurrency, myCreditRate);
1468 }
1469
1470
1471 final OceanusMoney myDebitCost = myDebitValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
1472
1473
1474 OceanusMoney myProfit = new OceanusMoney(myDebitValue);
1475 myProfit.subtractAmount(myDebitCost);
1476 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
1477 myProfit = new OceanusMoney(myProfit);
1478 myProfit.negate();
1479 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
1480
1481
1482 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDebitCost);
1483 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myCreditUnits);
1484 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myInvested);
1485 if (isForeignCredit) {
1486 final OceanusMoney myForeign = myInvested.convertCurrency(myCreditAsset.getCurrency().getCurrency(), myCreditRate);
1487 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myForeign);
1488 }
1489
1490
1491 myCreditUnits = myCreditAsset.getValues().getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1492 OceanusMoney myCreditValue = myCreditUnits.valueAtPrice(myCreditPrice);
1493 if (isForeignCredit) {
1494 myCreditValue = myCreditValue.convertCurrency(myCurrency, myCreditRate);
1495 }
1496
1497
1498 final MoneyWiseAnalysisSecurityValues myCreditValues = myCreditAsset.registerTransaction(theHelper);
1499 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myCreditPrice);
1500 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDVALUE, myCreditXferValue);
1501 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myDebitCost);
1502 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myCreditValue);
1503 if (isForeignCredit) {
1504 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myCreditRate);
1505 }
1506
1507
1508 final OceanusMoney myDeltaCost = new OceanusMoney(myDebitCost);
1509 myDeltaCost.negate();
1510 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1511 myDeltaCost.negate();
1512
1513
1514 myDebitUnits = new OceanusUnits(myDebitUnits);
1515 myDebitUnits.negate();
1516 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDebitUnits);
1517
1518
1519 myInvested = new OceanusMoney(myInvested);
1520 myInvested.negate();
1521 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myInvested);
1522 if (isForeignDebit) {
1523 myInvested = new OceanusMoney(myDebitValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED));
1524 myInvested.negate();
1525 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myInvested);
1526 }
1527
1528
1529 myDebitValues = myDebitAsset.registerTransaction(theHelper);
1530 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myDebitPrice);
1531 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myDebitValue);
1532 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDVALUE, myCreditXferValue);
1533 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myDeltaCost);
1534 if (isForeignDebit) {
1535 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myDebitRate);
1536 }
1537 }
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548 private void processStockAndCashTakeOver(final MoneyWiseSecurityHolding pDebit,
1549 final MoneyWiseSecurityHolding pCredit) {
1550
1551 final MoneyWiseSecurity myDebit = pDebit.getSecurity();
1552 final MoneyWiseSecurity myCredit = pCredit.getSecurity();
1553 final OceanusDate myDate = theHelper.getDate();
1554 final MoneyWiseTransAsset myReturnedCashAccount = theHelper.getReturnedCashAccount();
1555 final OceanusMoney myAmount = theHelper.getLocalReturnedCash();
1556
1557
1558 final MoneyWiseAnalysisSecurityBucket myDebitAsset = thePortfolioBuckets.getBucket(pDebit);
1559 MoneyWiseAnalysisSecurityValues myDebitValues = myDebitAsset.getValues();
1560 final MoneyWiseAnalysisSecurityBucket myCreditAsset = thePortfolioBuckets.getBucket(pCredit);
1561
1562
1563 final OceanusPrice myDebitPrice = thePriceMap.getPriceForDate(myDebit, myDate);
1564 final OceanusPrice myCreditPrice = thePriceMap.getPriceForDate(myCredit, myDate);
1565 final OceanusRatio myDebitRate = theHelper.getDebitExchangeRate();
1566 final OceanusRatio myCreditRate = theHelper.getCreditExchangeRate();
1567 final Currency myCurrency = theAnalysis.getCurrency().getCurrency();
1568
1569
1570 OceanusUnits myDebitUnits = myDebitValues.getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1571 OceanusMoney myDebitValue = myDebitUnits.valueAtPrice(myDebitPrice);
1572
1573
1574 OceanusUnits myCreditUnits = theHelper.getPartnerDeltaUnits();
1575 OceanusMoney myCreditXferValue = myCreditUnits.valueAtPrice(myCreditPrice);
1576
1577
1578 final boolean isForeignDebit = myDebitAsset.isForeignCurrency();
1579 if (isForeignDebit) {
1580 myDebitValue = myDebitValue.convertCurrency(myCurrency, myDebitRate);
1581 }
1582
1583
1584 final boolean isForeignCredit = myCreditAsset.isForeignCurrency();
1585 if (isForeignCredit) {
1586 myCreditXferValue = myCreditXferValue.convertCurrency(myCurrency, myCreditRate);
1587 }
1588
1589
1590 final OceanusMoney myConsideration = new OceanusMoney(myAmount);
1591 myConsideration.addAmount(myCreditXferValue);
1592
1593
1594 final OceanusMoney myCost = myDebitValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
1595 OceanusRatio myCostDilution = null;
1596 final OceanusMoney myCostXfer;
1597 final OceanusMoney myAllowedCost;
1598
1599
1600 final OceanusMoney myPortion = myDebitValue.valueAtRate(LIMIT_RATE);
1601 final boolean isLargeCash = (myAmount.compareTo(LIMIT_VALUE) > 0)
1602 && (myAmount.compareTo(myPortion) > 0);
1603
1604
1605 if (isLargeCash) {
1606
1607 myCostXfer = myCost.valueAtWeight(myCreditXferValue, myConsideration);
1608
1609
1610 myCostDilution = new OceanusRatio(myAmount, myConsideration);
1611
1612
1613 myAllowedCost = new OceanusMoney(myCost);
1614 myAllowedCost.subtractAmount(myCostXfer);
1615
1616
1617 } else {
1618
1619 myAllowedCost = myAmount.compareTo(myCost) > 0
1620 ? new OceanusMoney(myCost)
1621 : new OceanusMoney(myAmount);
1622
1623
1624 myCostXfer = new OceanusMoney(myCost);
1625 myCostXfer.subtractAmount(myAllowedCost);
1626 }
1627
1628
1629 final OceanusMoney myCapitalGain = new OceanusMoney(myAmount);
1630 myCapitalGain.subtractAmount(myAllowedCost);
1631 if (myCapitalGain.isNonZero()) {
1632
1633 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS, myCapitalGain);
1634
1635
1636 theCategoryBuckets.adjustStandardGain(theHelper, pDebit, myCapitalGain);
1637 }
1638
1639
1640 OceanusMoney myProfit = new OceanusMoney(myCreditXferValue);
1641 myProfit.subtractAmount(myCostXfer);
1642 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
1643 myProfit = new OceanusMoney(myProfit);
1644 myProfit.negate();
1645 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST, myProfit);
1646
1647
1648 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myCostXfer);
1649 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myCreditUnits);
1650 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myCostXfer);
1651 if (isForeignCredit) {
1652 final OceanusMoney myForeign = myCostXfer.convertCurrency(myCreditAsset.getCurrency().getCurrency(), myCreditRate);
1653 myCreditAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myForeign);
1654 }
1655
1656
1657 myCreditUnits = myCreditAsset.getValues().getUnitsValue(MoneyWiseAnalysisSecurityAttr.UNITS);
1658 OceanusMoney myCreditValue = myCreditUnits.valueAtPrice(myCreditPrice);
1659 if (isForeignCredit) {
1660 myCreditValue = myCreditValue.convertCurrency(myCurrency, myCreditRate);
1661 }
1662
1663
1664 final MoneyWiseAnalysisSecurityValues myCreditValues = myCreditAsset.registerTransaction(theHelper);
1665 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myCreditPrice);
1666 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDVALUE, myCreditXferValue);
1667 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myCostXfer);
1668 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myCreditValue);
1669 if (isForeignCredit) {
1670 myCreditValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myCreditRate);
1671 }
1672
1673
1674 final OceanusMoney myDeltaCost = new OceanusMoney(myCost);
1675 myDeltaCost.negate();
1676 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST, myDeltaCost);
1677
1678
1679 myDebitUnits = new OceanusUnits(myDebitUnits);
1680 myDebitUnits.negate();
1681 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.UNITS, myDebitUnits);
1682
1683
1684 OceanusMoney myInvested = myDebitValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED);
1685 myInvested = new OceanusMoney(myInvested);
1686 myInvested.setZero();
1687 myInvested.subtractAmount(myAmount);
1688 myInvested.subtractAmount(myCostXfer);
1689 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.INVESTED, myInvested);
1690 if (isForeignDebit) {
1691 myInvested = myInvested.convertCurrency(myDebitAsset.getCurrency().getCurrency(), myDebitRate);
1692 myInvested.negate();
1693 myDebitAsset.adjustCounter(MoneyWiseAnalysisSecurityAttr.FOREIGNINVESTED, myInvested);
1694 }
1695
1696
1697 myDebitValues = myDebitAsset.registerTransaction(theHelper);
1698 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.PRICE, myDebitPrice);
1699 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, myDebitValue);
1700 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.CONSIDERATION, myConsideration);
1701 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.RETURNEDCASH, myAmount);
1702 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDVALUE, myCreditXferValue);
1703 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.XFERREDCOST, myCostXfer);
1704 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.ALLOWEDCOST, myAllowedCost);
1705 if (myCostDilution != null) {
1706 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.COSTDILUTION, myCostDilution);
1707 }
1708 if (myCapitalGain.isNonZero()) {
1709 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.CAPITALGAIN, myCapitalGain);
1710 }
1711 if (isForeignDebit) {
1712 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.EXCHANGERATE, myDebitRate);
1713 }
1714 myDebitValues.setValue(MoneyWiseAnalysisSecurityAttr.CASHTYPE, isLargeCash
1715 ? MoneyWiseCashType.LARGECASH
1716 : MoneyWiseCashType.SMALLCASH);
1717
1718
1719 final MoneyWiseAnalysisAccountBucket<?> myBucket = getAccountBucket((MoneyWiseAssetBase) myReturnedCashAccount);
1720 myBucket.adjustForReturnedCashCredit(theHelper);
1721 }
1722
1723
1724
1725
1726
1727
1728
1729 private MoneyWiseAnalysisAccountBucket<?> getAccountBucket(final MoneyWiseAssetBase pAsset) {
1730 switch (pAsset.getAssetType()) {
1731 case DEPOSIT:
1732 return theDepositBuckets.getBucket((MoneyWiseDeposit) pAsset);
1733 case CASH:
1734 return theCashBuckets.getBucket((MoneyWiseCash) pAsset);
1735 case LOAN:
1736 return theLoanBuckets.getBucket((MoneyWiseLoan) pAsset);
1737 case PORTFOLIO:
1738 return thePortfolioBuckets.getCashBucket((MoneyWisePortfolio) pAsset);
1739 default:
1740 throw new IllegalArgumentException();
1741 }
1742 }
1743 }