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