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.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
21 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
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.MoneyWiseCash;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCash.MoneyWiseCashList;
26 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCashCategory;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCashCategory.MoneyWiseCashCategoryList;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee;
29 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
30 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory;
31 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory.MoneyWiseTransCategoryList;
32 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoClass;
33 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAssetCategory;
34 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
35 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
36 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency.MoneyWiseCurrencyList;
37 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
38 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransCategoryClass;
39 import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseIcon;
40 import io.github.tonywasher.joceanus.moneywise.ui.base.MoneyWiseAssetTable;
41 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
42 import io.github.tonywasher.joceanus.prometheus.ui.fieldset.PrometheusFieldSet;
43 import io.github.tonywasher.joceanus.prometheus.ui.fieldset.PrometheusFieldSetEvent;
44 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
45 import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControl.TethysUIIconMapSet;
46 import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
47 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUICharArrayTextAreaField;
48 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIIconButtonField;
49 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIMoneyEditField;
50 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIScrollButtonField;
51 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIStringEditField;
52 import io.github.tonywasher.joceanus.tethys.api.field.TethysUIFieldFactory;
53 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollItem;
54 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
55 import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollSubMenu;
56
57 import java.util.HashMap;
58 import java.util.Iterator;
59 import java.util.Map;
60
61
62
63
64 public class MoneyWiseCashDialog
65 extends MoneyWiseAssetDialog<MoneyWiseCash> {
66
67
68
69 private final PrometheusFieldSet<MoneyWiseCash> theFieldSet;
70
71
72
73
74 private Boolean theClosedState = Boolean.FALSE;
75
76
77
78
79
80
81
82
83 public MoneyWiseCashDialog(final TethysUIFactory<?> pFactory,
84 final PrometheusEditSet pEditSet,
85 final MoneyWiseAssetTable<MoneyWiseCash> pOwner) {
86
87 super(pFactory, pEditSet, pOwner);
88
89
90 theFieldSet = getFieldSet();
91 theFieldSet.setReporter(pOwner::showValidateError);
92
93
94 buildMainPanel(pFactory);
95
96
97 buildDetailsPanel(pFactory);
98
99
100 buildNotesPanel(pFactory);
101 }
102
103
104
105
106
107
108 private void buildMainPanel(final TethysUIFactory<?> pFactory) {
109
110 final TethysUIFieldFactory myFields = pFactory.fieldFactory();
111 final TethysUIStringEditField myName = myFields.newStringField();
112 final TethysUIStringEditField myDesc = myFields.newStringField();
113
114
115 final TethysUIScrollButtonField<MoneyWiseAssetCategory> myCategoryButton = myFields.newScrollField(MoneyWiseAssetCategory.class);
116 final TethysUIScrollButtonField<MoneyWiseCurrency> myCurrencyButton = myFields.newScrollField(MoneyWiseCurrency.class);
117 final TethysUIIconButtonField<Boolean> myClosedButton = myFields.newIconField(Boolean.class);
118
119
120 theFieldSet.addField(PrometheusDataResource.DATAITEM_FIELD_NAME, myName, MoneyWiseCash::getName);
121 theFieldSet.addField(PrometheusDataResource.DATAITEM_FIELD_DESC, myDesc, MoneyWiseCash::getDesc);
122 theFieldSet.addField(MoneyWiseBasicResource.CATEGORY_NAME, myCategoryButton, MoneyWiseCash::getCategory);
123 theFieldSet.addField(MoneyWiseStaticDataType.CURRENCY, myCurrencyButton, MoneyWiseCash::getAssetCurrency);
124 theFieldSet.addField(MoneyWiseBasicResource.ASSET_CLOSED, myClosedButton, MoneyWiseCash::isClosed);
125
126
127 myCategoryButton.setMenuConfigurator(c -> buildCategoryMenu(c, getItem()));
128 myCurrencyButton.setMenuConfigurator(c -> buildCurrencyMenu(c, getItem()));
129 final Map<Boolean, TethysUIIconMapSet<Boolean>> myMapSets = MoneyWiseIcon.configureLockedIconButton(pFactory);
130 myClosedButton.setIconMapSet(() -> myMapSets.get(theClosedState));
131
132
133 myName.setValidator(this::isValidName);
134 myDesc.setValidator(this::isValidDesc);
135 }
136
137
138
139
140
141
142 private void buildDetailsPanel(final TethysUIFactory<?> pFactory) {
143
144 theFieldSet.newPanel(TAB_DETAILS);
145
146
147 final TethysUIFieldFactory myFields = pFactory.fieldFactory();
148 final TethysUIMoneyEditField myOpening = myFields.newMoneyField();
149
150
151 final TethysUIScrollButtonField<MoneyWiseTransCategory> myAutoExpenseButton = myFields.newScrollField(MoneyWiseTransCategory.class);
152 final TethysUIScrollButtonField<MoneyWisePayee> myAutoPayeeButton = myFields.newScrollField(MoneyWisePayee.class);
153
154
155 theFieldSet.addField(MoneyWiseAccountInfoClass.AUTOEXPENSE, myAutoExpenseButton, MoneyWiseCash::getAutoExpense);
156 theFieldSet.addField(MoneyWiseAccountInfoClass.AUTOPAYEE, myAutoPayeeButton, MoneyWiseCash::getAutoPayee);
157 theFieldSet.addField(MoneyWiseAccountInfoClass.OPENINGBALANCE, myOpening, MoneyWiseCash::getOpeningBalance);
158
159
160 myAutoExpenseButton.setMenuConfigurator(c -> buildAutoExpenseMenu(c, getItem()));
161 myAutoPayeeButton.setMenuConfigurator(c -> buildAutoPayeeMenu(c, getItem()));
162 myOpening.setDeemedCurrency(() -> getItem().getCurrency());
163 }
164
165
166
167
168
169
170 private void buildNotesPanel(final TethysUIFactory<?> pFactory) {
171
172 final TethysUICharArrayTextAreaField myNotes = pFactory.fieldFactory().newCharArrayAreaField();
173
174
175 theFieldSet.newTextArea(TAB_NOTES, MoneyWiseAccountInfoClass.NOTES, myNotes, MoneyWiseCash::getNotes);
176
177
178 myNotes.setValidator(this::isValidNotes);
179 }
180
181 @Override
182 public void refreshData() {
183
184 final MoneyWiseCash myItem = getItem();
185 if (myItem != null) {
186 final MoneyWiseCashList myCash = getDataList(MoneyWiseBasicDataType.CASH, MoneyWiseCashList.class);
187 setItem(myCash.findItemById(myItem.getIndexedId()));
188 }
189
190
191 setEditable(false);
192 }
193
194 @Override
195 protected void adjustFields(final boolean isEditable) {
196
197 final MoneyWiseCash myCash = getItem();
198 final boolean bIsClosed = myCash.isClosed();
199 final boolean bIsActive = myCash.isActive();
200 final boolean bIsRelevant = myCash.isRelevant();
201 final boolean isAutoExpense = myCash.isAutoExpense();
202 final boolean bIsChangeable = !bIsActive && isEditable;
203
204
205 final boolean bShowClosed = bIsClosed || (bIsActive && !bIsRelevant);
206 theFieldSet.setFieldVisible(MoneyWiseBasicResource.ASSET_CLOSED, bShowClosed);
207
208
209 final boolean bEditClosed = bIsClosed || !bIsRelevant;
210 theFieldSet.setFieldEditable(MoneyWiseBasicResource.ASSET_CLOSED, isEditable && bEditClosed);
211 theClosedState = bEditClosed;
212
213
214 final boolean bShowDesc = isEditable || myCash.getDesc() != null;
215 theFieldSet.setFieldVisible(PrometheusDataResource.DATAITEM_FIELD_DESC, bShowDesc);
216
217
218 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.AUTOEXPENSE, isAutoExpense);
219 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.AUTOPAYEE, isAutoExpense);
220
221
222 final boolean bHasOpening = myCash.getOpeningBalance() != null;
223 final boolean bShowOpening = bIsChangeable || bHasOpening;
224 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.OPENINGBALANCE, !isAutoExpense && bShowOpening);
225
226
227 final boolean bShowNotes = isEditable || myCash.getNotes() != null;
228 theFieldSet.setFieldVisible(MoneyWiseAccountInfoClass.NOTES, bShowNotes);
229
230
231 theFieldSet.setFieldEditable(MoneyWiseBasicResource.CATEGORY_NAME, bIsChangeable);
232 theFieldSet.setFieldEditable(MoneyWiseStaticDataType.CURRENCY, bIsChangeable && !bHasOpening);
233
234
235 final boolean canEdit = isEditable && !bIsClosed;
236 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.AUTOEXPENSE, canEdit);
237 theFieldSet.setFieldEditable(MoneyWiseAccountInfoClass.AUTOPAYEE, canEdit);
238 }
239
240 @Override
241 protected void updateField(final PrometheusFieldSetEvent pUpdate) throws OceanusException {
242
243 final MetisDataFieldId myField = pUpdate.getFieldId();
244 final MoneyWiseCash myCash = getItem();
245
246
247 if (PrometheusDataResource.DATAITEM_FIELD_NAME.equals(myField)) {
248
249 myCash.setName(pUpdate.getValue(String.class));
250 } else if (PrometheusDataResource.DATAITEM_FIELD_DESC.equals(myField)) {
251
252 myCash.setDescription(pUpdate.getValue(String.class));
253 } else if (MoneyWiseBasicResource.CATEGORY_NAME.equals(myField)) {
254
255 myCash.setCategory(pUpdate.getValue(MoneyWiseCashCategory.class));
256 myCash.autoCorrect();
257 } else if (MoneyWiseStaticDataType.CURRENCY.equals(myField)) {
258
259 myCash.setAssetCurrency(pUpdate.getValue(MoneyWiseCurrency.class));
260 } else if (MoneyWiseBasicResource.ASSET_CLOSED.equals(myField)) {
261
262 myCash.setClosed(pUpdate.getValue(Boolean.class));
263 } else if (MoneyWiseAccountInfoClass.AUTOEXPENSE.equals(myField)) {
264
265 myCash.setAutoExpense(pUpdate.getValue(MoneyWiseTransCategory.class));
266 } else if (MoneyWiseAccountInfoClass.AUTOPAYEE.equals(myField)) {
267
268 myCash.setAutoPayee(pUpdate.getValue(MoneyWisePayee.class));
269 } else if (MoneyWiseAccountInfoClass.OPENINGBALANCE.equals(myField)) {
270
271 myCash.setOpeningBalance(pUpdate.getValue(OceanusMoney.class));
272 } else if (MoneyWiseAccountInfoClass.NOTES.equals(myField)) {
273
274 myCash.setNotes(pUpdate.getValue(char[].class));
275 }
276 }
277
278 @Override
279 protected void declareGoToItems(final boolean pUpdates) {
280 final MoneyWiseCash myItem = getItem();
281 final MoneyWisePayee myAutoPayee = myItem.getAutoPayee();
282 if (!pUpdates) {
283 final MoneyWiseCashCategory myCategory = myItem.getCategory();
284 final MoneyWiseTransCategory myAutoExpense = myItem.getAutoExpense();
285 final MoneyWiseCurrency myCurrency = myItem.getAssetCurrency();
286 declareGoToItem(myCategory);
287 declareGoToItem(myCurrency);
288 declareGoToItem(myAutoExpense);
289 }
290 declareGoToItem(myAutoPayee);
291 }
292
293
294
295
296
297
298
299 public void buildCategoryMenu(final TethysUIScrollMenu<MoneyWiseAssetCategory> pMenu,
300 final MoneyWiseCash pCash) {
301
302 pMenu.removeAllItems();
303
304
305 final MoneyWiseCashCategory myCurr = pCash.getCategory();
306 TethysUIScrollItem<MoneyWiseAssetCategory> myActive = null;
307
308
309 final MoneyWiseCashCategoryList myCategories = getDataList(MoneyWiseBasicDataType.CASHCATEGORY, MoneyWiseCashCategoryList.class);
310
311
312 final Map<String, TethysUIScrollSubMenu<MoneyWiseAssetCategory>> myMap = new HashMap<>();
313
314
315 final Iterator<MoneyWiseCashCategory> myIterator = myCategories.iterator();
316 while (myIterator.hasNext()) {
317 final MoneyWiseCashCategory myCategory = myIterator.next();
318
319
320 final boolean bIgnore = myCategory.isDeleted() || myCategory.isCategoryClass(MoneyWiseCashCategoryClass.PARENT);
321 if (bIgnore) {
322 continue;
323 }
324
325
326 final MoneyWiseCashCategory myParent = myCategory.getParentCategory();
327 final String myParentName = myParent.getName();
328 final TethysUIScrollSubMenu<MoneyWiseAssetCategory> myMenu = myMap.computeIfAbsent(myParentName, pMenu::addSubMenu);
329
330
331 final TethysUIScrollItem<MoneyWiseAssetCategory> myItem = myMenu.getSubMenu().addItem(myCategory, myCategory.getSubCategory());
332
333
334 if (myCategory.equals(myCurr)) {
335 myActive = myItem;
336 }
337 }
338
339
340 if (myActive != null) {
341 myActive.scrollToItem();
342 }
343 }
344
345
346
347
348
349
350
351 private void buildAutoExpenseMenu(final TethysUIScrollMenu<MoneyWiseTransCategory> pMenu,
352 final MoneyWiseCash pCash) {
353
354 pMenu.removeAllItems();
355
356
357 final MoneyWiseTransCategory myCurr = pCash.getAutoExpense();
358 TethysUIScrollItem<MoneyWiseTransCategory> myActive = null;
359
360
361 final MoneyWiseTransCategoryList myCategories = getDataList(MoneyWiseBasicDataType.TRANSCATEGORY, MoneyWiseTransCategoryList.class);
362
363
364 final Map<String, TethysUIScrollSubMenu<MoneyWiseTransCategory>> myMap = new HashMap<>();
365
366
367 final Iterator<MoneyWiseTransCategory> myIterator = myCategories.iterator();
368 while (myIterator.hasNext()) {
369 final MoneyWiseTransCategory myCategory = myIterator.next();
370
371
372 final MoneyWiseTransCategoryClass myClass = myCategory.getCategoryTypeClass();
373 boolean bIgnore = myCategory.isDeleted() || myClass.canParentCategory();
374 bIgnore |= !myClass.isExpense();
375 if (bIgnore) {
376 continue;
377 }
378
379
380 final MoneyWiseTransCategory myParent = myCategory.getParentCategory();
381 final String myParentName = myParent.getName();
382 final TethysUIScrollSubMenu<MoneyWiseTransCategory> myMenu = myMap.computeIfAbsent(myParentName, pMenu::addSubMenu);
383
384
385 final TethysUIScrollItem<MoneyWiseTransCategory> myItem = myMenu.getSubMenu().addItem(myCategory);
386
387
388 if (myCategory.equals(myCurr)) {
389 myActive = myItem;
390 }
391 }
392
393
394 if (myActive != null) {
395 myActive.scrollToItem();
396 }
397 }
398
399
400
401
402
403
404
405 private void buildAutoPayeeMenu(final TethysUIScrollMenu<MoneyWisePayee> pMenu,
406 final MoneyWiseCash pCash) {
407
408 pMenu.removeAllItems();
409
410
411 final MoneyWisePayee myCurr = pCash.getAutoPayee();
412 TethysUIScrollItem<MoneyWisePayee> myActive = null;
413
414
415 final MoneyWisePayeeList myPayees = getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class);
416
417
418 final Iterator<MoneyWisePayee> myIterator = myPayees.iterator();
419 while (myIterator.hasNext()) {
420 final MoneyWisePayee myPayee = myIterator.next();
421
422
423 if (myPayee.isDeleted() || myPayee.isClosed()) {
424 continue;
425 }
426
427
428 final TethysUIScrollItem<MoneyWisePayee> myItem = pMenu.addItem(myPayee);
429
430
431 if (myPayee.equals(myCurr)) {
432
433 myActive = myItem;
434 }
435 }
436
437
438 if (myActive != null) {
439 myActive.scrollToItem();
440 }
441 }
442
443
444
445
446
447
448
449 public void buildCurrencyMenu(final TethysUIScrollMenu<MoneyWiseCurrency> pMenu,
450 final MoneyWiseCash pCash) {
451
452 pMenu.removeAllItems();
453
454
455 final MoneyWiseCurrency myCurr = pCash.getAssetCurrency();
456 TethysUIScrollItem<MoneyWiseCurrency> myActive = null;
457
458
459 final MoneyWiseCurrencyList myCurrencies = getDataList(MoneyWiseStaticDataType.CURRENCY, MoneyWiseCurrencyList.class);
460
461
462 final Iterator<MoneyWiseCurrency> myIterator = myCurrencies.iterator();
463 while (myIterator.hasNext()) {
464 final MoneyWiseCurrency myCurrency = myIterator.next();
465
466
467 final boolean bIgnore = myCurrency.isDeleted() || !myCurrency.getEnabled();
468 if (bIgnore) {
469 continue;
470 }
471
472
473 final TethysUIScrollItem<MoneyWiseCurrency> myItem = pMenu.addItem(myCurrency);
474
475
476 if (myCurrency.equals(myCurr)) {
477
478 myActive = myItem;
479 }
480 }
481
482
483 if (myActive != null) {
484 myActive.scrollToItem();
485 }
486 }
487 }