1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.ui.dialog;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
20 import io.github.tonywasher.joceanus.metis.field.MetisFieldRequired;
21 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase;
22 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
23 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
24 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
26 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseRegion;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseRegion.MoneyWiseRegionList;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity;
29 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity.MoneyWiseSecurityList;
30 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoClass;
31 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAssetCategory;
32 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
33 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency.MoneyWiseCurrencyList;
34 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityClass;
35 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityType;
36 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityType.MoneyWiseSecurityTypeList;
37 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
38 import io.github.tonywasher.joceanus.moneywise.data.validate.MoneyWiseValidateSecurity;
39 import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseIcon;
40 import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseUIResource;
41 import io.github.tonywasher.joceanus.moneywise.ui.base.MoneyWiseUIAssetTable;
42 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseView;
43 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
44 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
45 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
46 import io.github.tonywasher.joceanus.prometheus.ui.fieldset.PrometheusFieldSet;
47 import io.github.tonywasher.joceanus.prometheus.ui.fieldset.PrometheusFieldSetEvent;
48 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
49 import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControl.TethysUIIconMapSet;
50 import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
51 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUICharArrayTextAreaField;
52 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIIconButtonField;
53 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIPriceEditField;
54 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIScrollButtonField;
55 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIStringEditField;
56 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIFieldFactory;
57 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollItem;
58 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
59
60 import java.util.Iterator;
61 import java.util.Map;
62
63
64
65
66 public class MoneyWiseUISecurityDialog
67 extends MoneyWiseUIAssetDialog<MoneyWiseSecurity> {
68
69
70
71 private static final String TAB_PRICES = MoneyWiseUIResource.SECURITYPANEL_TAB_PRICES.getValue();
72
73
74
75
76 private final PrometheusFieldSet<MoneyWiseSecurity> theFieldSet;
77
78
79
80
81 private final MoneyWiseUISecurityPriceTable thePrices;
82
83
84
85
86 private Boolean theClosedState = Boolean.FALSE;
87
88
89
90
91
92
93
94
95
96 public MoneyWiseUISecurityDialog(final TethysUIFactory<?> pFactory,
97 final MoneyWiseView pView,
98 final PrometheusEditSet pEditSet,
99 final MoneyWiseUIAssetTable<MoneyWiseSecurity> pOwner) {
100
101 super(pFactory, pEditSet, pOwner);
102
103
104 theFieldSet = getFieldSet();
105 theFieldSet.setReporter(pOwner::showValidateError);
106
107
108 buildMainPanel(pFactory);
109
110
111 buildDetailsPanel(pFactory);
112
113
114 buildNotesPanel(pFactory);
115
116
117 thePrices = new MoneyWiseUISecurityPriceTable(pView, getEditSet(), pOwner.getErrorPanel());
118 theFieldSet.newTable(TAB_PRICES, thePrices);
119
120
121 thePrices.getEventRegistrar().addEventListener(e -> {
122 updateActions();
123 fireStateChanged();
124 });
125 }
126
127
128
129
130
131
132 private void buildMainPanel(final TethysUIFactory<?> pFactory) {
133
134 final TethysUIFieldFactory myFields = pFactory.fieldFactory();
135 final TethysUIStringEditField myName = myFields.newStringField();
136 final TethysUIStringEditField myDesc = myFields.newStringField();
137
138
139 final TethysUIScrollButtonField<MoneyWiseAssetCategory> myTypeButton = myFields.newScrollField(MoneyWiseAssetCategory.class);
140 final TethysUIScrollButtonField<MoneyWisePayee> myParentButton = myFields.newScrollField(MoneyWisePayee.class);
141 final TethysUIScrollButtonField<MoneyWiseCurrency> myCurrencyButton = myFields.newScrollField(MoneyWiseCurrency.class);
142 final TethysUIIconButtonField<Boolean> myClosedButton = myFields.newIconField(Boolean.class);
143
144
145 theFieldSet.addField(PrometheusDataResource.DATAITEM_FIELD_NAME, myName, MoneyWiseSecurity::getName);
146 theFieldSet.addField(PrometheusDataResource.DATAITEM_FIELD_DESC, myDesc, MoneyWiseSecurity::getDesc);
147 theFieldSet.addField(MoneyWiseBasicResource.CATEGORY_NAME, myTypeButton, MoneyWiseSecurity::getCategory);
148 theFieldSet.addField(MoneyWiseBasicResource.ASSET_PARENT, myParentButton, MoneyWiseSecurity::getParent);
149 theFieldSet.addField(MoneyWiseStaticDataType.CURRENCY, myCurrencyButton, MoneyWiseSecurity::getAssetCurrency);
150 theFieldSet.addField(MoneyWiseBasicResource.ASSET_CLOSED, myClosedButton, MoneyWiseSecurity::isClosed);
151
152
153 myTypeButton.setMenuConfigurator(c -> buildSecTypeMenu(c, getItem()));
154 myParentButton.setMenuConfigurator(c -> buildParentMenu(c, getItem()));
155 myCurrencyButton.setMenuConfigurator(c -> buildCurrencyMenu(c, getItem()));
156 final Map<Boolean, TethysUIIconMapSet<Boolean>> myMapSets = MoneyWiseIcon.configureLockedIconButton(pFactory);
157 myClosedButton.setIconMapSet(() -> myMapSets.get(theClosedState));
158
159
160 myName.setValidator(this::isValidName);
161 myDesc.setValidator(this::isValidDesc);
162 }
163
164
165
166
167
168
169 private void buildDetailsPanel(final TethysUIFactory<?> pFactory) {
170
171 theFieldSet.newPanel(TAB_DETAILS);
172
173
174 final TethysUIFieldFactory myFields = pFactory.fieldFactory();
175 final TethysUIStringEditField mySymbol = myFields.newStringField();
176 final TethysUIPriceEditField myPrice = myFields.newPriceField();
177
178
179 final TethysUIScrollButtonField<MoneyWiseRegion> myRegionButton = myFields.newScrollField(MoneyWiseRegion.class);
180 final TethysUIScrollButtonField<MoneyWiseSecurity> myStockButton = myFields.newScrollField(MoneyWiseSecurity.class);
181
182
183 theFieldSet.addField(MoneyWiseAccountInfoClass.SYMBOL, mySymbol, MoneyWiseSecurity::getSymbol);
184 theFieldSet.addField(MoneyWiseAccountInfoClass.REGION, myRegionButton, MoneyWiseSecurity::getRegion);
185 theFieldSet.addField(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK, myStockButton, MoneyWiseSecurity::getUnderlyingStock);
186 theFieldSet.addField(MoneyWiseAccountInfoClass.OPTIONPRICE, myPrice, MoneyWiseSecurity::getOptionPrice);
187
188
189 myRegionButton.setMenuConfigurator(c -> buildRegionMenu(c, getItem()));
190 myStockButton.setMenuConfigurator(c -> buildStockMenu(c, getItem()));
191 myPrice.setDeemedCurrency(() -> getItem().getCurrency());
192
193
194 mySymbol.setValidator(this::isValidSymbol);
195 }
196
197
198
199
200
201
202 private void buildNotesPanel(final TethysUIFactory<?> pFactory) {
203
204 final TethysUIFieldFactory myFields = pFactory.fieldFactory();
205 final TethysUICharArrayTextAreaField myNotes = myFields.newCharArrayAreaField();
206
207
208 theFieldSet.newTextArea(TAB_NOTES, MoneyWiseAccountInfoClass.NOTES, myNotes, MoneyWiseSecurity::getNotes);
209
210
211 myNotes.setValidator(this::isValidNotes);
212 }
213
214 @Override
215 public void refreshData() {
216
217 final MoneyWiseSecurity myItem = getItem();
218 if (myItem != null) {
219 final MoneyWiseSecurityList mySecurities = getDataList(MoneyWiseBasicDataType.SECURITY, MoneyWiseSecurityList.class);
220 setItem(mySecurities.findItemById(myItem.getIndexedId()));
221 }
222
223
224 thePrices.refreshData();
225
226
227 setEditable(false);
228 }
229
230 @Override
231 protected void adjustFields(final boolean isEditable) {
232
233 final MoneyWiseSecurity mySecurity = getItem();
234 final boolean bIsClosed = mySecurity.isClosed();
235 final boolean bIsActive = mySecurity.isActive();
236 final boolean bIsRelevant = mySecurity.isRelevant();
237
238
239 final boolean bShowClosed = bIsClosed || (bIsActive && !bIsRelevant);
240 theFieldSet.setFieldVisible(MoneyWiseBasicResource.ASSET_CLOSED, bShowClosed);
241
242
243 final boolean bEditClosed = bIsClosed
244 ? !mySecurity.getParent().isClosed()
245 : !bIsRelevant;
246 theFieldSet.setFieldEditable(MoneyWiseBasicResource.ASSET_CLOSED, isEditable && bEditClosed);
247 theClosedState = bEditClosed;
248
249
250 final boolean bShowDesc = isEditable || mySecurity.getDesc() != null;
251 theFieldSet.setFieldVisible(PrometheusDataResource.DATAITEM_FIELD_DESC, bShowDesc);
252
253
254 final boolean bShowNotes = isEditable || mySecurity.getNotes() != null;
255 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.NOTES, bShowNotes);
256
257
258 boolean bEditField = isEditable && isEditableField(mySecurity, MoneyWiseAccountInfoClass.SYMBOL);
259 boolean bShowField = bEditField || mySecurity.getSymbol() != null;
260 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.SYMBOL, bShowField);
261 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.SYMBOL, bEditField);
262
263
264 bEditField = isEditable && isEditableField(mySecurity, MoneyWiseAccountInfoClass.REGION);
265 bShowField = bEditField || mySecurity.getRegion() != null;
266 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.REGION, bShowField);
267 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.REGION, bEditField);
268
269
270 bEditField = isEditable && isEditableField(mySecurity, MoneyWiseAccountInfoClass.UNDERLYINGSTOCK);
271 bShowField = bEditField || mySecurity.getRegion() != null;
272 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK, bShowField);
273 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK, bEditField);
274
275
276 bEditField = isEditable && isEditableField(mySecurity, MoneyWiseAccountInfoClass.OPTIONPRICE);
277 bShowField = bEditField || mySecurity.getRegion() != null;
278 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.OPTIONPRICE, bShowField);
279 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.OPTIONPRICE, bEditField);
280
281
282 theFieldSet.setFieldEditable(MoneyWiseBasicResource.CATEGORY_NAME, isEditable && !bIsActive);
283 theFieldSet.setFieldEditable(MoneyWiseStaticDataType.CURRENCY, isEditable && !bIsActive);
284
285
286 theFieldSet.setFieldEditable(MoneyWiseBasicResource.ASSET_PARENT, isEditable && !bIsClosed);
287 }
288
289
290
291
292
293
294
295
296 public static boolean isEditableField(final MoneyWiseSecurity pSecurity,
297 final MoneyWiseAccountInfoClass pField) {
298
299 final MoneyWiseValidateSecurity myValidator = (MoneyWiseValidateSecurity) pSecurity.getList().getValidator();
300 final MetisFieldRequired isRequired = myValidator.isClassRequired(pField);
301 return !isRequired.equals(MetisFieldRequired.NOTALLOWED);
302 }
303
304 @Override
305 protected void updateField(final PrometheusFieldSetEvent pUpdate) throws OceanusException {
306
307 final MetisDataFieldId myField = pUpdate.getFieldId();
308 final MoneyWiseSecurity mySecurity = getItem();
309
310
311 if (PrometheusDataResource.DATAITEM_FIELD_NAME.equals(myField)) {
312
313 mySecurity.setName(pUpdate.getValue(String.class));
314 } else if (PrometheusDataResource.DATAITEM_FIELD_DESC.equals(myField)) {
315
316 mySecurity.setDescription(pUpdate.getValue(String.class));
317 } else if (MoneyWiseBasicResource.CATEGORY_NAME.equals(myField)) {
318
319 mySecurity.setCategory(pUpdate.getValue(MoneyWiseSecurityType.class));
320 mySecurity.autoCorrect();
321 } else if (MoneyWiseBasicResource.ASSET_PARENT.equals(myField)) {
322
323 mySecurity.setParent(pUpdate.getValue(MoneyWisePayee.class));
324 } else if (MoneyWiseStaticDataType.CURRENCY.equals(myField)) {
325
326 mySecurity.setAssetCurrency(pUpdate.getValue(MoneyWiseCurrency.class));
327 } else if (MoneyWiseBasicResource.ASSET_CLOSED.equals(myField)) {
328
329 mySecurity.setClosed(pUpdate.getValue(Boolean.class));
330 } else if (MoneyWiseAccountInfoClass.SYMBOL.equals(myField)) {
331
332 mySecurity.setSymbol(pUpdate.getValue(String.class));
333 } else if (MoneyWiseAccountInfoClass.REGION.equals(myField)) {
334
335 mySecurity.setRegion(pUpdate.getValue(MoneyWiseRegion.class));
336 } else if (MoneyWiseAccountInfoClass.UNDERLYINGSTOCK.equals(myField)) {
337
338 mySecurity.setUnderlyingStock(pUpdate.getValue(MoneyWiseSecurity.class));
339 } else if (MoneyWiseAccountInfoClass.OPTIONPRICE.equals(myField)) {
340
341 mySecurity.setOptionPrice(pUpdate.getValue(OceanusPrice.class));
342 } else if (MoneyWiseAccountInfoClass.NOTES.equals(myField)) {
343
344 mySecurity.setNotes(pUpdate.getValue(char[].class));
345 }
346 }
347
348 @Override
349 protected void declareGoToItems(final boolean pUpdates) {
350 final MoneyWiseSecurity myItem = getItem();
351 final MoneyWiseAssetBase myParent = myItem.getParent();
352 if (!pUpdates) {
353 final MoneyWiseSecurityType myType = myItem.getCategory();
354 final MoneyWiseCurrency myCurrency = myItem.getAssetCurrency();
355 final MoneyWiseRegion myRegion = myItem.getRegion();
356 declareGoToItem(myType);
357 declareGoToItem(myRegion);
358 declareGoToItem(myCurrency);
359 }
360 declareGoToItem(myParent);
361 }
362
363
364
365
366
367
368
369 public void addNewPrice(final MoneyWiseSecurity pSecurity) throws OceanusException {
370
371 thePrices.addNewPrice(pSecurity);
372 }
373
374 @Override
375 public void setEditable(final boolean isEditable) {
376
377 thePrices.setEditable(isEditable);
378
379
380 super.setEditable(isEditable);
381 }
382
383 @Override
384 protected void refreshAfterUpdate() {
385
386 super.refreshAfterUpdate();
387
388
389 thePrices.refreshAfterUpdate();
390 }
391
392
393
394
395
396
397
398 public void buildSecTypeMenu(final TethysUIScrollMenu<MoneyWiseAssetCategory> pMenu,
399 final MoneyWiseSecurity pSecurity) {
400
401 pMenu.removeAllItems();
402
403
404 final MoneyWiseSecurityType myCurr = pSecurity.getCategory();
405 TethysUIScrollItem<MoneyWiseAssetCategory> myActive = null;
406
407
408 final MoneyWiseSecurityTypeList myTypes = getDataList(MoneyWiseStaticDataType.SECURITYTYPE, MoneyWiseSecurityTypeList.class);
409
410
411 final Iterator<MoneyWiseSecurityType> myIterator = myTypes.iterator();
412 while (myIterator.hasNext()) {
413 final MoneyWiseSecurityType myType = myIterator.next();
414
415
416 final boolean bIgnore = myType.isDeleted() || !myType.getEnabled();
417 if (bIgnore) {
418 continue;
419 }
420
421
422 final TethysUIScrollItem<MoneyWiseAssetCategory> myItem = pMenu.addItem(myType);
423
424
425 if (myType.equals(myCurr)) {
426
427 myActive = myItem;
428 }
429 }
430
431
432 if (myActive != null) {
433 myActive.scrollToItem();
434 }
435 }
436
437
438
439
440
441
442
443 public void buildParentMenu(final TethysUIScrollMenu<MoneyWisePayee> pMenu,
444 final MoneyWiseSecurity pSecurity) {
445
446 pMenu.removeAllItems();
447
448
449 final MoneyWiseSecurityClass myType = pSecurity.getCategoryClass();
450 final MoneyWisePayee myCurr = pSecurity.getParent();
451 TethysUIScrollItem<MoneyWisePayee> myActive = null;
452
453
454 final MoneyWisePayeeList myPayees = getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class);
455
456
457 final Iterator<MoneyWisePayee> myIterator = myPayees.iterator();
458 while (myIterator.hasNext()) {
459 final MoneyWisePayee myPayee = myIterator.next();
460
461
462 boolean bIgnore = myPayee.isDeleted() || !myPayee.getCategoryClass().canParentSecurity(myType);
463 bIgnore |= myPayee.isClosed();
464 if (bIgnore) {
465 continue;
466 }
467
468
469 final TethysUIScrollItem<MoneyWisePayee> myItem = pMenu.addItem(myPayee);
470
471
472 if (myPayee.equals(myCurr)) {
473
474 myActive = myItem;
475 }
476 }
477
478
479 if (myActive != null) {
480 myActive.scrollToItem();
481 }
482 }
483
484
485
486
487
488
489
490 public void buildRegionMenu(final TethysUIScrollMenu<MoneyWiseRegion> pMenu,
491 final MoneyWiseSecurity pSecurity) {
492
493 pMenu.removeAllItems();
494
495
496 final MoneyWiseRegion myCurr = pSecurity.getRegion();
497 TethysUIScrollItem<MoneyWiseRegion> myActive = null;
498
499
500 final MoneyWiseRegionList myRegions = getDataList(MoneyWiseBasicDataType.REGION, MoneyWiseRegionList.class);
501
502
503 final Iterator<MoneyWiseRegion> myIterator = myRegions.iterator();
504 while (myIterator.hasNext()) {
505 final MoneyWiseRegion myRegion = myIterator.next();
506
507
508 final boolean bIgnore = myRegion.isDeleted();
509 if (bIgnore) {
510 continue;
511 }
512
513
514 final TethysUIScrollItem<MoneyWiseRegion> myItem = pMenu.addItem(myRegion);
515
516
517 if (myRegion.equals(myCurr)) {
518
519 myActive = myItem;
520 }
521 }
522
523
524 if (myActive != null) {
525 myActive.scrollToItem();
526 }
527 }
528
529
530
531
532
533
534
535 public void buildStockMenu(final TethysUIScrollMenu<MoneyWiseSecurity> pMenu,
536 final MoneyWiseSecurity pSecurity) {
537
538 pMenu.removeAllItems();
539
540
541 final MoneyWiseSecurity myCurr = pSecurity.getUnderlyingStock();
542 TethysUIScrollItem<MoneyWiseSecurity> myActive = null;
543
544
545 final MoneyWiseSecurityList mySecurities = getDataList(MoneyWiseBasicDataType.SECURITY, MoneyWiseSecurityList.class);
546
547
548 final Iterator<MoneyWiseSecurity> myIterator = mySecurities.iterator();
549 while (myIterator.hasNext()) {
550 final MoneyWiseSecurity mySecurity = myIterator.next();
551
552
553 boolean bIgnore = mySecurity.isDeleted();
554 bIgnore |= !mySecurity.getCategoryClass().isShares();
555 if (bIgnore) {
556 continue;
557 }
558
559
560 final TethysUIScrollItem<MoneyWiseSecurity> myItem = pMenu.addItem(mySecurity);
561
562
563 if (mySecurity.equals(myCurr)) {
564
565 myActive = myItem;
566 }
567 }
568
569
570 if (myActive != null) {
571 myActive.scrollToItem();
572 }
573 }
574
575
576
577
578
579
580
581 public void buildCurrencyMenu(final TethysUIScrollMenu<MoneyWiseCurrency> pMenu,
582 final MoneyWiseSecurity pSecurity) {
583
584 pMenu.removeAllItems();
585
586
587 final MoneyWiseCurrency myCurr = pSecurity.getAssetCurrency();
588 TethysUIScrollItem<MoneyWiseCurrency> myActive = null;
589
590
591 final MoneyWiseCurrencyList myCurrencies = getDataList(MoneyWiseStaticDataType.CURRENCY, MoneyWiseCurrencyList.class);
592
593
594 final Iterator<MoneyWiseCurrency> myIterator = myCurrencies.iterator();
595 while (myIterator.hasNext()) {
596 final MoneyWiseCurrency myCurrency = myIterator.next();
597
598
599 final boolean bIgnore = myCurrency.isDeleted() || !myCurrency.getEnabled();
600 if (bIgnore) {
601 continue;
602 }
603
604
605 final TethysUIScrollItem<MoneyWiseCurrency> myItem = pMenu.addItem(myCurrency);
606
607
608 if (myCurrency.equals(myCurr)) {
609
610 myActive = myItem;
611 }
612 }
613
614
615 if (myActive != null) {
616 myActive.scrollToItem();
617 }
618 }
619 }