1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.data.validate;
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.date.OceanusDateRange;
22 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
23 import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogManager;
24 import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogger;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase;
26 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase.MoneyWiseAssetBaseList;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetDirection;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
29 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCash.MoneyWiseCashList;
30 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDeposit.MoneyWiseDepositList;
31 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan.MoneyWiseLoanList;
32 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee;
33 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
34 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
35 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio.MoneyWisePortfolioList;
36 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityHolding;
37 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityHolding.MoneyWiseSecurityHoldingMap;
38 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
39 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory;
40 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory.MoneyWiseTransCategoryList;
41 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction;
42 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction.MoneyWiseTransactionList;
43 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransCategoryClass;
44 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
45
46 import java.util.Currency;
47 import java.util.Iterator;
48
49
50
51
52
53
54 public class MoneyWiseValidateTransDefaults {
55
56
57
58 private static final OceanusLogger LOGGER = OceanusLogManager.getLogger(MoneyWiseValidateTransDefaults.class);
59
60
61
62
63 private final MoneyWiseValidateTransaction theValidator;
64
65
66
67
68 private PrometheusEditSet theEditSet;
69
70
71
72
73 private OceanusDateRange theRange;
74
75
76
77
78
79
80 public MoneyWiseValidateTransDefaults(final MoneyWiseValidateTransaction pValidator) {
81 theValidator = pValidator;
82 }
83
84
85
86
87
88
89 public OceanusDateRange getRange() {
90 return theRange;
91 }
92
93
94
95
96
97
98 public void setRange(final OceanusDateRange pRange) {
99 theRange = pRange;
100 }
101
102
103
104
105
106
107
108 public void autoCorrect(final MoneyWiseTransaction pTrans) throws OceanusException {
109
110 final MoneyWiseTransAsset myAccount = pTrans.getAccount();
111 MoneyWiseTransAsset myPartner = pTrans.getPartner();
112 MoneyWiseTransCategory myCategory = pTrans.getCategory();
113 final MoneyWiseAssetDirection myDir = pTrans.getDirection();
114 final OceanusMoney myAmount = pTrans.getAmount();
115 final Currency myCurrency = myAccount.getCurrency();
116 theEditSet = theValidator.getEditSet();
117
118
119 if (!theValidator.isValidCategory(myAccount, myCategory)) {
120
121 myCategory = getDefaultCategoryForAccount(myAccount);
122 pTrans.setCategory(myCategory);
123 }
124
125
126 if (!theValidator.isValidDirection(myAccount, myCategory, myDir)) {
127
128 pTrans.switchDirection();
129 }
130
131
132 if (!theValidator.isValidPartner(myAccount, myCategory, myPartner)) {
133
134 myPartner = getDefaultPartnerForAccountAndCategory(myAccount, myCategory);
135 pTrans.setPartner(myPartner);
136 }
137
138
139 if (myCategory.getCategoryTypeClass().needsNullAmount()) {
140 if (myAmount != null) {
141
142 pTrans.setAmount(null);
143 }
144
145
146 } else {
147 if (myAmount == null) {
148
149 pTrans.setAmount(new OceanusMoney(myCurrency));
150
151
152 } else if (!myCurrency.equals(myAmount.getCurrency())) {
153
154 pTrans.setAmount(myAmount.changeCurrency(myCurrency));
155 }
156 }
157
158
159 final MoneyWiseValidateTransInfoSet myInfoSet = theValidator.getInfoSetValidator();
160 myInfoSet.autoCorrect(pTrans.getInfoSet());
161 }
162
163
164
165
166
167
168 private MoneyWiseTransaction newTransaction() {
169
170 return new MoneyWiseTransaction(theEditSet.getDataList(MoneyWiseBasicDataType.TRANSACTION, MoneyWiseTransactionList.class));
171 }
172
173
174
175
176
177
178
179 public MoneyWiseTransaction buildTransaction(final Object pKey) {
180
181 try {
182 theEditSet = theValidator.getEditSet();
183 if (pKey == null) {
184
185 return buildDefaultTransaction();
186 }
187 if (pKey instanceof MoneyWisePayee myPayee) {
188
189 return buildDefaultTransactionForPayee(myPayee);
190 }
191 if (pKey instanceof MoneyWiseSecurityHolding myHolding) {
192
193 return buildDefaultTransactionForHolding(myHolding);
194 }
195 if (pKey instanceof MoneyWiseTransAsset myAsset) {
196
197 return buildDefaultTransactionForAccount(myAsset);
198 }
199 if (pKey instanceof MoneyWiseTransCategory myCategory) {
200
201 return buildDefaultTransactionForCategory(myCategory);
202 }
203 } catch (OceanusException e) {
204 LOGGER.error("Unable to build transaction", e);
205 }
206
207
208 return null;
209 }
210
211
212
213
214
215
216
217 private void buildStandardDetails(final MoneyWiseTransaction pTrans) throws OceanusException {
218
219 final OceanusDateRange myRange = theRange;
220
221
222 pTrans.setDirection(MoneyWiseAssetDirection.TO);
223
224
225 OceanusDate myDate = new OceanusDate();
226 final int iResult = myRange.compareToDate(myDate);
227 if (iResult < 0) {
228 myDate = myRange.getEnd();
229 } else if (iResult > 0) {
230 myDate = myRange.getStart();
231 }
232 pTrans.setDate(myDate);
233
234
235 final MoneyWiseTransAsset myAccount = pTrans.getAccount();
236 final Currency myCurrency = myAccount.getCurrency();
237 pTrans.setAmount(new OceanusMoney(myCurrency));
238 }
239
240
241
242
243
244
245
246 private MoneyWiseTransaction buildDefaultTransaction() throws OceanusException {
247 final MoneyWiseTransCategory myCategory = getDefaultCategory();
248 if (myCategory == null) {
249 return null;
250 }
251
252
253 return buildDefaultTransactionForCategory(myCategory);
254 }
255
256
257
258
259
260
261
262
263 private MoneyWiseTransaction buildDefaultTransactionForPayee(final MoneyWisePayee pPayee) throws OceanusException {
264
265 if (pPayee.isClosed() || pPayee.isHidden()) {
266 return null;
267 }
268
269
270 final MoneyWiseTransaction myTrans = newTransaction();
271
272
273 myTrans.setPartner(pPayee);
274
275
276 final MoneyWiseTransCategory myCategory = getDefaultCategory();
277 if (myCategory == null) {
278 return null;
279 }
280 myTrans.setCategory(myCategory);
281
282
283 final MoneyWiseTransAsset myAccount = getDefaultAccountForCategory(myCategory);
284 if (myAccount == null) {
285 return null;
286 }
287 myTrans.setAccount(myAccount);
288
289
290 if (!theValidator.isValidPartner(myAccount, myCategory, pPayee)) {
291 return null;
292 }
293
294
295 buildStandardDetails(myTrans);
296
297
298 autoCorrect(myTrans);
299
300
301 return myTrans;
302 }
303
304
305
306
307
308
309
310
311 private MoneyWiseTransaction buildDefaultTransactionForCategory(final MoneyWiseTransCategory pCategory) throws OceanusException {
312
313 if (pCategory.isHidden()) {
314 return null;
315 }
316
317
318 final MoneyWiseTransaction myTrans = newTransaction();
319
320
321 myTrans.setCategory(pCategory);
322
323
324 final MoneyWiseTransAsset myAccount = getDefaultAccountForCategory(pCategory);
325 if (myAccount == null) {
326 return null;
327 }
328 myTrans.setAccount(myAccount);
329
330
331 final MoneyWiseTransAsset myPartner = getDefaultPartnerForAccountAndCategory(myAccount, pCategory);
332 if (myPartner == null) {
333 return null;
334 }
335 myTrans.setPartner(myPartner);
336
337
338 buildStandardDetails(myTrans);
339
340
341 autoCorrect(myTrans);
342
343
344 return myTrans;
345 }
346
347
348
349
350
351
352
353
354 private MoneyWiseTransaction buildDefaultTransactionForAccount(final MoneyWiseTransAsset pAccount) throws OceanusException {
355
356 if (pAccount.isClosed()) {
357 return null;
358 }
359
360
361 final MoneyWiseTransaction myTrans = newTransaction();
362
363
364 myTrans.setAccount(pAccount);
365
366
367 final MoneyWiseTransCategory myCategory = getDefaultCategory();
368 if (myCategory == null) {
369 return null;
370 }
371 myTrans.setCategory(myCategory);
372
373
374 final MoneyWiseTransAsset myPartner = getDefaultPartnerForAccountAndCategory(pAccount, myCategory);
375 if (myPartner == null) {
376 return null;
377 }
378 myTrans.setPartner(myPartner);
379
380
381 buildStandardDetails(myTrans);
382
383
384 autoCorrect(myTrans);
385
386
387 return myTrans;
388 }
389
390
391
392
393
394
395
396
397 private MoneyWiseTransaction buildDefaultTransactionForHolding(final MoneyWiseSecurityHolding pHolding) throws OceanusException {
398
399 if (pHolding.isClosed()) {
400 return null;
401 }
402
403
404 final MoneyWiseTransaction myTrans = newTransaction();
405
406
407 myTrans.setAccount(pHolding);
408
409
410 final MoneyWiseTransCategory myCategory = getDefaultCategoryForAccount(pHolding);
411 myTrans.setCategory(myCategory);
412
413
414 final MoneyWiseTransAsset myPartner = getDefaultPartnerForAccountAndCategory(pHolding, myCategory);
415 if (myPartner == null) {
416 return null;
417 }
418 myTrans.setPartner(myPartner);
419
420
421 buildStandardDetails(myTrans);
422
423
424 autoCorrect(myTrans);
425
426
427 return myTrans;
428 }
429
430
431
432
433
434
435
436 private MoneyWiseTransAsset getDefaultAccountForCategory(final MoneyWiseTransCategory pCategory) {
437
438 MoneyWiseTransAsset myAccount = getDefaultAssetForCategory(theEditSet.getDataList(MoneyWiseBasicDataType.DEPOSIT, MoneyWiseDepositList.class), pCategory);
439 if (myAccount == null) {
440 myAccount = getDefaultAssetForCategory(theEditSet.getDataList(MoneyWiseBasicDataType.CASH, MoneyWiseCashList.class), pCategory);
441 }
442 if (myAccount == null) {
443 myAccount = getDefaultAssetForCategory(theEditSet.getDataList(MoneyWiseBasicDataType.LOAN, MoneyWiseLoanList.class), pCategory);
444 }
445
446
447 if (myAccount == null) {
448 myAccount = getDefaultHolding(pCategory);
449 }
450
451
452 if (myAccount == null) {
453 myAccount = getDefaultAssetForCategory(theEditSet.getDataList(MoneyWiseBasicDataType.PORTFOLIO, MoneyWisePortfolioList.class), pCategory);
454 }
455
456
457 return myAccount;
458 }
459
460
461
462
463
464
465 private MoneyWiseTransCategory getDefaultCategory() {
466
467 MoneyWiseTransCategory myCategory = getDefaultCategory(CategoryType.EXPENSE);
468 if (myCategory == null) {
469 myCategory = getDefaultCategory(CategoryType.INCOME);
470 }
471 if (myCategory == null) {
472 myCategory = getDefaultCategory(CategoryType.TRANSFER);
473 }
474
475
476 return myCategory;
477 }
478
479
480
481
482
483
484
485 private MoneyWiseTransCategory getDefaultCategory(final CategoryType pType) {
486
487 final MoneyWiseTransCategoryList myCategories = theEditSet.getDataList(MoneyWiseBasicDataType.TRANSCATEGORY, MoneyWiseTransCategoryList.class);
488
489
490 final Iterator<MoneyWiseTransCategory> myIterator = myCategories.iterator();
491 while (myIterator.hasNext()) {
492 final MoneyWiseTransCategory myCategory = myIterator.next();
493
494
495 final MoneyWiseTransCategoryClass myClass = myCategory.getCategoryTypeClass();
496 if (myCategory.isDeleted() || myClass.canParentCategory()) {
497 continue;
498 }
499
500
501 switch (pType) {
502 case EXPENSE:
503 if (myClass.isExpense()) {
504 return myCategory;
505 }
506 break;
507 case INCOME:
508 if (myClass.isIncome()) {
509 return myCategory;
510 }
511 break;
512 case TRANSFER:
513 default:
514 if (myClass.isTransfer()) {
515 return myCategory;
516 }
517 break;
518 }
519 }
520
521
522 return null;
523 }
524
525
526
527
528
529
530
531 private MoneyWiseTransCategory getDefaultCategoryForAccount(final MoneyWiseTransAsset pAccount) {
532
533 final MoneyWiseTransCategoryList myCategories = theEditSet.getDataList(MoneyWiseBasicDataType.TRANSCATEGORY, MoneyWiseTransCategoryList.class);
534
535
536 final Iterator<MoneyWiseTransCategory> myIterator = myCategories.iterator();
537 while (myIterator.hasNext()) {
538 final MoneyWiseTransCategory myCategory = myIterator.next();
539
540
541 final MoneyWiseTransCategoryClass myClass = myCategory.getCategoryTypeClass();
542 if (myCategory.isDeleted() || myClass.canParentCategory()) {
543 continue;
544 }
545
546
547 if (theValidator.isValidCategory(pAccount, myCategory)) {
548 return myCategory;
549 }
550 }
551
552
553 throw new IllegalArgumentException();
554 }
555
556
557
558
559
560
561
562
563 private MoneyWiseTransAsset getDefaultPartnerForAccountAndCategory(final MoneyWiseTransAsset pAccount,
564 final MoneyWiseTransCategory pCategory) {
565
566 MoneyWiseTransAsset myPartner = getDefaultPartnerAsset(theEditSet.getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class), pAccount, pCategory);
567
568
569 if (myPartner == null) {
570 myPartner = getDefaultPartnerAsset(theEditSet.getDataList(MoneyWiseBasicDataType.DEPOSIT, MoneyWiseDepositList.class), pAccount, pCategory);
571 }
572 if (myPartner == null) {
573 myPartner = getDefaultPartnerAsset(theEditSet.getDataList(MoneyWiseBasicDataType.CASH, MoneyWiseCashList.class), pAccount, pCategory);
574 }
575 if (myPartner == null) {
576 myPartner = getDefaultPartnerAsset(theEditSet.getDataList(MoneyWiseBasicDataType.LOAN, MoneyWiseLoanList.class), pAccount, pCategory);
577 }
578
579
580 if (myPartner == null) {
581 myPartner = getDefaultPartnerAsset(theEditSet.getDataList(MoneyWiseBasicDataType.PORTFOLIO, MoneyWisePortfolioList.class), pAccount, pCategory);
582 }
583
584
585 if (myPartner == null) {
586 myPartner = getDefaultPartnerHolding(pAccount, pCategory);
587 }
588
589
590 return myPartner;
591 }
592
593
594
595
596
597
598
599
600
601 private <X extends MoneyWiseAssetBase> MoneyWiseTransAsset getDefaultAssetForCategory(final MoneyWiseAssetBaseList<X> pList,
602 final MoneyWiseTransCategory pCategory) {
603
604 final Iterator<X> myIterator = pList.iterator();
605 while (myIterator.hasNext()) {
606 final X myAsset = myIterator.next();
607
608
609 if (myAsset.isDeleted() || myAsset.isClosed()) {
610 continue;
611 }
612
613
614 if (theValidator.isValidCategory(myAsset, pCategory)) {
615 return myAsset;
616 }
617 }
618
619
620 return null;
621 }
622
623
624
625
626
627
628
629
630
631
632 private <X extends MoneyWiseAssetBase> MoneyWiseTransAsset getDefaultPartnerAsset(final MoneyWiseAssetBaseList<X> pList,
633 final MoneyWiseTransAsset pAccount,
634 final MoneyWiseTransCategory pCategory) {
635
636 final Iterator<X> myIterator = pList.iterator();
637 while (myIterator.hasNext()) {
638 final X myAsset = myIterator.next();
639
640
641 if (myAsset.isDeleted() || myAsset.isClosed()) {
642 continue;
643 }
644
645
646 if (theValidator.isValidPartner(pAccount, pCategory, myAsset)) {
647 return myAsset;
648 }
649 }
650
651
652 return null;
653 }
654
655
656
657
658
659
660
661 private MoneyWiseSecurityHolding getDefaultHolding(final MoneyWiseTransCategory pCategory) {
662
663 final MoneyWisePortfolioList myPortfolios = theEditSet.getDataList(MoneyWiseBasicDataType.PORTFOLIO, MoneyWisePortfolioList.class);
664 final MoneyWiseSecurityHoldingMap myMap = myPortfolios.getSecurityHoldingsMap();
665
666
667 final Iterator<MoneyWisePortfolio> myPortIterator = myPortfolios.iterator();
668 while (myPortIterator.hasNext()) {
669 final MoneyWisePortfolio myPortfolio = myPortIterator.next();
670
671
672 if (myPortfolio.isDeleted() || myPortfolio.isClosed()) {
673 continue;
674 }
675
676
677 final Iterator<MoneyWiseSecurityHolding> myExistIterator = myMap.existingIterator(myPortfolio);
678 if (myExistIterator != null) {
679
680 while (myExistIterator.hasNext()) {
681 final MoneyWiseSecurityHolding myHolding = myExistIterator.next();
682
683
684 if (theValidator.isValidCategory(myHolding, pCategory)) {
685 return myHolding;
686 }
687 }
688 }
689 }
690
691
692 return null;
693 }
694
695
696
697
698
699
700
701
702 private MoneyWiseSecurityHolding getDefaultPartnerHolding(final MoneyWiseTransAsset pAccount,
703 final MoneyWiseTransCategory pCategory) {
704
705 final MoneyWisePortfolioList myPortfolios = theEditSet.getDataList(MoneyWiseBasicDataType.PORTFOLIO, MoneyWisePortfolioList.class);
706 final MoneyWiseSecurityHoldingMap myMap = myPortfolios.getSecurityHoldingsMap();
707
708
709 final Iterator<MoneyWisePortfolio> myPortIterator = myPortfolios.iterator();
710 while (myPortIterator.hasNext()) {
711 final MoneyWisePortfolio myPortfolio = myPortIterator.next();
712
713
714 if (myPortfolio.isDeleted() || myPortfolio.isClosed()) {
715 continue;
716 }
717
718
719 final Iterator<MoneyWiseSecurityHolding> myExistIterator = myMap.existingIterator(myPortfolio);
720 if (myExistIterator != null) {
721
722 while (myExistIterator.hasNext()) {
723 final MoneyWiseSecurityHolding myHolding = myExistIterator.next();
724
725
726 if (theValidator.isValidPartner(pAccount, pCategory, myHolding)) {
727 return myHolding;
728 }
729 }
730 }
731 }
732
733
734 return null;
735 }
736
737
738
739
740 private enum CategoryType {
741
742
743
744 EXPENSE,
745
746
747
748
749 INCOME,
750
751
752
753
754 TRANSFER;
755 }
756 }