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.metis.field.MetisFieldRequired;
20 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
21 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDepositInfoSet;
22 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoanInfoSet;
23 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseRegion;
24 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseRegion.MoneyWiseRegionList;
25 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity;
26 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity.MoneyWiseSecurityList;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityInfo;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityInfoSet;
29 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoClass;
30 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
31 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityClass;
32 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
33 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
34 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInfoClass;
35 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
36 import io.github.tonywasher.joceanus.prometheus.validate.PrometheusValidateInfoSet;
37
38 import java.util.Currency;
39 import java.util.Iterator;
40
41
42
43
44 public class MoneyWiseValidateSecurityInfoSet
45 extends PrometheusValidateInfoSet<MoneyWiseSecurityInfo> {
46
47
48
49 private static final String NAME_NEWSYMBOL = "SYMBOL";
50
51 @Override
52 public MoneyWiseSecurity getOwner() {
53 return (MoneyWiseSecurity) super.getOwner();
54 }
55
56 @Override
57 public MetisFieldRequired isClassRequired(final PrometheusDataInfoClass pClass) {
58
59 final MoneyWiseSecurity mySec = getOwner();
60 final MoneyWiseSecurityClass myType = mySec.getCategoryClass();
61
62
63 if (myType == null) {
64 return MetisFieldRequired.NOTALLOWED;
65 }
66
67 return switch ((MoneyWiseAccountInfoClass) pClass) {
68
69 case NOTES -> MetisFieldRequired.CANEXIST;
70
71
72 case SYMBOL -> myType.needsSymbol()
73 ? MetisFieldRequired.MUSTEXIST
74 : MetisFieldRequired.NOTALLOWED;
75
76
77 case REGION -> myType.needsRegion()
78 ? MetisFieldRequired.MUSTEXIST
79 : MetisFieldRequired.NOTALLOWED;
80
81
82 case UNDERLYINGSTOCK, OPTIONPRICE -> myType.isOption()
83 ? MetisFieldRequired.MUSTEXIST
84 : MetisFieldRequired.NOTALLOWED;
85
86
87 default -> MetisFieldRequired.NOTALLOWED;
88 };
89 }
90
91 @Override
92 public void validateClass(final MoneyWiseSecurityInfo pInfo,
93 final PrometheusDataInfoClass pClass) {
94
95 switch ((MoneyWiseAccountInfoClass) pClass) {
96 case NOTES:
97 validateNotes(pInfo);
98 break;
99 case SYMBOL:
100 validateSymbol(pInfo);
101 break;
102 case UNDERLYINGSTOCK:
103 validateUnderlyingStock(pInfo);
104 break;
105 case OPTIONPRICE:
106 validateOptionPrice(pInfo);
107 break;
108 default:
109 break;
110 }
111 }
112
113
114
115
116
117
118 private void validateNotes(final MoneyWiseSecurityInfo pInfo) {
119 final char[] myArray = pInfo.getValue(char[].class);
120 if (myArray.length > MoneyWiseAccountInfoClass.NOTES.getMaximumLength()) {
121 getOwner().addError(PrometheusDataItem.ERROR_LENGTH, MoneyWiseSecurityInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.NOTES));
122 }
123 }
124
125
126
127
128
129
130 private void validateSymbol(final MoneyWiseSecurityInfo pInfo) {
131 final String mySymbol = pInfo.getValue(String.class);
132 if (mySymbol.length() > MoneyWiseAccountInfoClass.SYMBOL.getMaximumLength()) {
133 getOwner().addError(PrometheusDataItem.ERROR_LENGTH, MoneyWiseSecurityInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.SYMBOL));
134 }
135 }
136
137
138
139
140
141
142 private void validateUnderlyingStock(final MoneyWiseSecurityInfo pInfo) {
143 final MoneyWiseSecurity myStock = pInfo.getValue(MoneyWiseSecurity.class);
144 if (!myStock.getCategoryClass().isShares()) {
145 getOwner().addError("Invalid underlying stock", MoneyWiseSecurityInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK));
146 }
147 if (!myStock.getCurrency().equals(getOwner().getCurrency())) {
148 getOwner().addError(MoneyWiseDepositInfoSet.ERROR_CURRENCY, MoneyWiseLoanInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK));
149 }
150 }
151
152
153
154
155
156
157 private void validateOptionPrice(final MoneyWiseSecurityInfo pInfo) {
158 final OceanusPrice myPrice = pInfo.getValue(OceanusPrice.class);
159 if (myPrice.isZero()) {
160 getOwner().addError(PrometheusDataItem.ERROR_ZERO, MoneyWiseSecurityInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.OPTIONPRICE));
161 } else if (!myPrice.isPositive()) {
162 getOwner().addError(PrometheusDataItem.ERROR_NEGATIVE, MoneyWiseSecurityInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.OPTIONPRICE));
163 }
164 if (!myPrice.getCurrency().equals(getOwner().getCurrency())) {
165 getOwner().addError(MoneyWiseDepositInfoSet.ERROR_CURRENCY, MoneyWiseLoanInfoSet.getFieldForClass(MoneyWiseAccountInfoClass.OPTIONPRICE));
166 }
167 }
168
169 @Override
170 protected void setDefault(final PrometheusDataInfoClass pClass) throws OceanusException {
171
172 switch ((MoneyWiseAccountInfoClass) pClass) {
173 case SYMBOL:
174 getInfoSet().setValue(pClass, getUniqueSymbol());
175 break;
176 case REGION:
177 getInfoSet().setValue(pClass, getDefaultRegion());
178 break;
179 case UNDERLYINGSTOCK:
180 getInfoSet().setValue(pClass, getDefaultUnderlyingStock());
181 break;
182 case OPTIONPRICE:
183 getInfoSet().setValue(pClass, getDefaultOptionPrice());
184 break;
185 default:
186 break;
187 }
188 }
189
190
191
192
193
194
195 private String getUniqueSymbol() {
196
197 final MoneyWiseSecurityList mySecurities = getOwner().getList();
198
199
200 final String myBase = NAME_NEWSYMBOL;
201 int iNextId = 1;
202
203
204 String mySymbol = myBase;
205 while (true) {
206
207 if (mySecurities.findItemBySymbol(mySymbol) == null) {
208 return mySymbol;
209 }
210
211
212 mySymbol = myBase.concat(Integer.toString(iNextId++));
213 }
214 }
215
216
217
218
219
220
221 private MoneyWiseRegion getDefaultRegion() {
222
223 final MoneyWiseRegionList myRegions
224 = getEditSet().getDataList(MoneyWiseBasicDataType.REGION, MoneyWiseRegionList.class);
225
226
227 final Iterator<MoneyWiseRegion> myIterator = myRegions.iterator();
228 while (myIterator.hasNext()) {
229 final MoneyWiseRegion myRegion = myIterator.next();
230
231
232 if (!myRegion.isDeleted()) {
233 return myRegion;
234 }
235 }
236
237
238 return null;
239 }
240
241
242
243
244
245
246 private MoneyWiseSecurity getDefaultUnderlyingStock() {
247
248 final MoneyWiseSecurityList mySecurities = getOwner().getList();
249
250
251 final Iterator<MoneyWiseSecurity> myIterator = mySecurities.iterator();
252 while (myIterator.hasNext()) {
253 final MoneyWiseSecurity mySecurity = myIterator.next();
254
255
256 if (mySecurity.isDeleted()) {
257 continue;
258 }
259
260
261 if (mySecurity.getCategoryClass().isShares()) {
262 return mySecurity;
263 }
264 }
265
266
267 return null;
268 }
269
270
271
272
273
274
275 private OceanusPrice getDefaultOptionPrice() {
276
277 final MoneyWiseSecurity myUnderlying = getOwner().getUnderlyingStock();
278
279
280 if (myUnderlying == null) {
281 return null;
282 }
283
284 final MoneyWiseCurrency myCurrency = myUnderlying.getAssetCurrency();
285 return OceanusPrice.getWholeUnits(1, myCurrency.getCurrency());
286 }
287
288 @Override
289 protected void autoCorrect(final PrometheusDataInfoClass pClass) throws OceanusException {
290
291 switch ((MoneyWiseAccountInfoClass) pClass) {
292 case UNDERLYINGSTOCK:
293 autoCorrectUnderlyingStock();
294 break;
295 case OPTIONPRICE:
296 autoCorrectOptionPrice();
297 break;
298 default:
299 break;
300 }
301 }
302
303
304
305
306
307
308 private void autoCorrectUnderlyingStock() throws OceanusException {
309
310 MoneyWiseSecurity myStock = getOwner().getUnderlyingStock();
311
312
313 if (!myStock.getCurrency().equals(getOwner().getCurrency())) {
314
315 myStock = getDefaultUnderlyingStock();
316 getInfoSet().setValue(MoneyWiseAccountInfoClass.UNDERLYINGSTOCK, myStock);
317 }
318 }
319
320
321
322
323
324
325 private void autoCorrectOptionPrice() throws OceanusException {
326
327 OceanusPrice myPrice = getOwner().getOptionPrice();
328 final MoneyWiseCurrency myAssetCurrency = getOwner().getAssetCurrency();
329 final Currency myCurrency = myAssetCurrency.getCurrency();
330
331
332 if (!myPrice.getCurrency().equals(myCurrency)) {
333 myPrice = myPrice.changeCurrency(myCurrency);
334 getInfoSet().setValue(MoneyWiseAccountInfoClass.OPTIONPRICE, myPrice);
335 }
336 }
337 }