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