MoneyWiseSpotSecurityPrice.java
/*
* MoneyWise: Finance Application
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.moneywise.views;
import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
import io.github.tonywasher.joceanus.metis.data.MetisDataEditState;
import io.github.tonywasher.joceanus.metis.data.MetisDataState;
import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataSet;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityPrice;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysis;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisManager;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket.MoneyWiseAnalysisPortfolioBucketList;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket.MoneyWiseAnalysisSecurityBucketList;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedValues;
import java.util.Iterator;
import java.util.ListIterator;
/**
* Extension of SecurityPrice to cater for spot prices.
*
* @author Tony Washer
*/
public final class MoneyWiseSpotSecurityPrice
extends MoneyWiseSecurityPrice {
/**
* Object name.
*/
public static final String OBJECT_NAME = MoneyWiseSpotSecurityPrice.class.getSimpleName();
/**
* List name.
*/
public static final String LIST_NAME = OBJECT_NAME + "s";
/**
* Report fields.
*/
@SuppressWarnings("rawtypes")
private static final MetisFieldSet<MoneyWiseSpotSecurityPrice> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSpotSecurityPrice.class);
/*
* The fields.
*/
static {
FIELD_DEFS.declareLocalField(MoneyWiseViewResource.SPOTEVENT_PREVDATE, MoneyWiseSpotSecurityPrice::getPrevDate);
FIELD_DEFS.declareLocalField(MoneyWiseViewResource.SPOTPRICE_PREVPRICE, MoneyWiseSpotSecurityPrice::getPrevPrice);
}
/**
* the previous date.
*/
private OceanusDate thePrevDate;
/**
* the previous price.
*/
private OceanusPrice thePrevPrice;
/**
* isDisabled.
*/
private boolean isDisabled;
/**
* Constructor for a new SpotPrice where no price data exists.
*
* @param pList the Spot Price List
* @param pSecurity the price for the date
*/
private MoneyWiseSpotSecurityPrice(final MoneyWiseSpotSecurityList pList,
final MoneyWiseSecurity pSecurity) {
super(pList);
/* Store base values */
setSecurity(pSecurity);
}
@Override
public MetisFieldSetDef getDataFieldSet() {
return FIELD_DEFS;
}
/**
* Obtain previous price.
*
* @return the price.
*/
public OceanusPrice getPrevPrice() {
return thePrevPrice;
}
/**
* Set previous price.
*
* @param pPrice the price
*/
protected void setPrevPrice(final OceanusPrice pPrice) {
thePrevPrice = pPrice;
}
/**
* Obtain previous date.
*
* @return the date.
*/
public OceanusDate getPrevDate() {
return thePrevDate;
}
/**
* Set previous date.
*
* @param pDate the date
*/
protected void setPrevDate(final OceanusDate pDate) {
thePrevDate = pDate;
}
@Override
public boolean isDisabled() {
return isDisabled;
}
/**
* Set disabled.
*
* @param pDisabled the flag
*/
protected void setDisabled(final boolean pDisabled) {
isDisabled = pDisabled;
}
/**
* Validate the line.
*/
@Override
public void validate() {
setValidEdit();
}
/* Is this row locked */
@Override
public boolean isLocked() {
return isDeleted();
}
/**
* Note that this item has been validated.
*/
@Override
public void setValidEdit() {
setEditState(hasHistory()
? MetisDataEditState.VALID
: MetisDataEditState.CLEAN);
}
@Override
public OceanusPrice getPrice() {
/* Switch on state */
switch (getState()) {
case NEW:
case CHANGED:
case RECOVERED:
case CLEAN:
return super.getPrice();
default:
return null;
}
}
@Override
public MetisDataState getState() {
final PrometheusEncryptedValues myCurr = getValues();
final PrometheusEncryptedValues myBase = getOriginalValues();
/* If we have no changes we are CLEAN */
if (myCurr.getVersion() == 0) {
return MetisDataState.CLEAN;
}
/* If the original price is Null */
if (myBase.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE) == null) {
/* Return status */
return myCurr.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE) == null
? MetisDataState.DELNEW
: MetisDataState.NEW;
}
/* If we are deleted return so */
return myCurr.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_PRICE) == null
? MetisDataState.DELETED
: MetisDataState.CHANGED;
}
/**
* The Spot Prices List class.
*/
public static class MoneyWiseSpotSecurityList
extends MoneyWiseSecurityPriceBaseList<MoneyWiseSpotSecurityPrice> {
/**
* Report fields.
*/
@SuppressWarnings("rawtypes")
private static final MetisFieldSet<MoneyWiseSpotSecurityList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseSpotSecurityList.class);
/*
* The fields.
*/
static {
FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.PORTFOLIO, MoneyWiseSpotSecurityList::getPortfolio);
FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, MoneyWiseSpotSecurityList::getDate);
FIELD_DEFS.declareLocalField(MoneyWiseViewResource.SPOTEVENT_NEXTDATE, MoneyWiseSpotSecurityList::getNext);
FIELD_DEFS.declareLocalField(MoneyWiseViewResource.SPOTEVENT_PREVDATE, MoneyWiseSpotSecurityList::getPrev);
}
/**
* The date.
*/
private final OceanusDate theDate;
/**
* The view.
*/
private final MoneyWiseView theView;
/**
* The portfolio.
*/
private final MoneyWisePortfolio thePortfolio;
/**
* The next date.
*/
private OceanusDate theNext;
/**
* The previous date.
*/
private OceanusDate thePrev;
/**
* Constructor.
*
* @param pView the view
* @param pPortfolio the portfolio
* @param pDate the date
*/
public MoneyWiseSpotSecurityList(final MoneyWiseView pView,
final MoneyWisePortfolio pPortfolio,
final OceanusDate pDate) {
/* Build initial list */
super(pView.getData(), MoneyWiseSpotSecurityPrice.class, MoneyWiseBasicDataType.SECURITYPRICE);
setStyle(PrometheusListStyle.EDIT);
ensureMap();
/* Store parameters */
theDate = pDate;
theView = pView;
thePortfolio = pPortfolio;
/* Obtain the portfolio bucket */
final MoneyWiseAnalysisManager myManager = theView.getAnalysisManager();
final MoneyWiseAnalysis myAnalysis = myManager.getAnalysis();
final MoneyWiseAnalysisPortfolioBucketList myPortfolios = myAnalysis.getPortfolios();
final MoneyWiseAnalysisPortfolioBucket myBucket = myPortfolios.findItemById(thePortfolio.getIndexedId());
if (myBucket == null) {
return;
}
final MoneyWiseAnalysisSecurityBucketList mySecurities = myBucket.getSecurities();
/* Loop through the Securities */
final OceanusDate myDate = new OceanusDate(theDate);
final Iterator<MoneyWiseAnalysisSecurityBucket> mySecIterator = mySecurities.iterator();
while (mySecIterator.hasNext()) {
final MoneyWiseAnalysisSecurityBucket mySecBucket = mySecIterator.next();
final MoneyWiseSecurity mySecurity = mySecBucket.getSecurity();
/* Ignore Options */
if (mySecurity.getCategoryClass().isOption()) {
continue;
}
/* Create a SpotPrice entry */
final MoneyWiseSpotSecurityPrice mySpot = new MoneyWiseSpotSecurityPrice(this, mySecurity);
mySpot.setIndexedId(mySecurity.getIndexedId());
mySpot.setDate(myDate);
mySpot.setDisabled(!mySecBucket.isActive());
add(mySpot);
}
/* Set the base for this list */
final MoneyWiseDataSet myData = theView.getData();
final MoneyWiseSecurityPriceList myPrices = myData.getSecurityPrices();
setBase(myPrices);
/* Loop through the prices */
final ListIterator<MoneyWiseSecurityPrice> myIterator = myPrices.listIterator(myPrices.size());
while (myIterator.hasPrevious()) {
final MoneyWiseSecurityPrice myPrice = myIterator.previous();
/* Access the Spot Price and ignore if not relevant/deleted */
final MoneyWiseSecurity mySecurity = myPrice.getSecurity();
final MoneyWiseSpotSecurityPrice mySpot = findItemById(mySecurity.getIndexedId());
if (mySpot == null || myPrice.isDeleted()) {
continue;
}
/* Test the Date */
final int iDiff = theDate.compareTo(myPrice.getDate());
/* If we are past the date */
if (iDiff < 0) {
/* Record the next date and break the loop */
theNext = myPrice.getDate();
break;
}
/* If we are exactly the date */
if (iDiff == 0) {
/* Set price */
mySpot.setValuePrice(myPrice.getPriceField());
/* Link to base and re-establish state */
mySpot.setBase(myPrice);
/* else we are a previous date */
} else {
/* Set previous date and value */
mySpot.setPrevDate(myPrice.getDate());
mySpot.setPrevPrice(myPrice.getPrice());
/* Record the latest previous date */
thePrev = myPrice.getDate();
}
}
}
@SuppressWarnings("rawtypes")
@Override
public MetisFieldSet<MoneyWiseSpotSecurityList> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public String listName() {
return MoneyWiseSpotSecurityList.class.getSimpleName();
}
@Override
public MetisFieldSetDef getItemFields() {
return MoneyWiseSpotSecurityPrice.FIELD_DEFS;
}
@Override
protected MoneyWiseSpotSecurityList getEmptyList(final PrometheusListStyle pStyle) {
throw new UnsupportedOperationException();
}
@Override
public MoneyWiseDataSet getDataSet() {
return (MoneyWiseDataSet) super.getDataSet();
}
/**
* Obtain the portfolio.
*
* @return the portfolio
*/
private MoneyWisePortfolio getPortfolio() {
return thePortfolio;
}
/**
* Obtain the date.
*
* @return the date
*/
private OceanusDate getDate() {
return theDate;
}
/**
* Obtain the next date.
*
* @return the date
*/
public OceanusDate getNext() {
return theNext;
}
/**
* Obtain the previous date.
*
* @return the date
*/
public OceanusDate getPrev() {
return thePrev;
}
/* Is this list locked */
@Override
public boolean isLocked() {
return false;
}
/* Disable Add a new item */
@Override
public MoneyWiseSpotSecurityPrice addCopyItem(final PrometheusDataItem pElement) {
throw new UnsupportedOperationException();
}
@Override
public MoneyWiseSpotSecurityPrice addNewItem() {
throw new UnsupportedOperationException();
}
@Override
public MoneyWiseSpotSecurityPrice addValuesItem(final PrometheusDataValues pValues) {
throw new UnsupportedOperationException();
}
}
}