MoneyWiseTransInfo.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.data.basic;
import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransTag.MoneyWiseTransTagList;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction.MoneyWiseTransactionList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransInfoClass;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransInfoType;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransInfoType.MoneyWiseTransInfoTypeList;
import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInfoClass;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInfoItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
import java.util.Iterator;
/**
* Representation of an information extension of an event.
*
* @author Tony Washer
*/
public class MoneyWiseTransInfo
extends PrometheusDataInfoItem {
/**
* Object name.
*/
public static final String OBJECT_NAME = MoneyWiseBasicDataType.TRANSACTIONINFO.getItemName();
/**
* List name.
*/
public static final String LIST_NAME = MoneyWiseBasicDataType.TRANSACTIONINFO.getListName();
/**
* Local Report fields.
*/
private static final MetisFieldSet<MoneyWiseTransInfo> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseTransInfo.class);
/**
* Copy Constructor.
*
* @param pList the list
* @param pInfo The Info to copy
*/
protected MoneyWiseTransInfo(final MoneyWiseTransInfoList pList,
final MoneyWiseTransInfo pInfo) {
/* Set standard values */
super(pList, pInfo);
}
/**
* Edit Constructor.
*
* @param pList the list
* @param pTransaction the transaction
* @param pType the type
*/
private MoneyWiseTransInfo(final MoneyWiseTransInfoList pList,
final MoneyWiseTransaction pTransaction,
final MoneyWiseTransInfoType pType) {
/* Initialise the item */
super(pList);
setNextDataKeySet();
/* Record the Detail */
setValueInfoType(pType);
setValueOwner(pTransaction);
}
/**
* Values constructor.
*
* @param pList the List to add to
* @param pValues the values constructor
* @throws OceanusException on error
*/
private MoneyWiseTransInfo(final MoneyWiseTransInfoList pList,
final PrometheusDataValues pValues) throws OceanusException {
/* Initialise the item */
super(pList, pValues);
/* Protect against exceptions */
try {
/* Resolve links */
final MoneyWiseDataSet myData = getDataSet();
resolveDataLink(PrometheusDataResource.DATAINFO_TYPE, myData.getTransInfoTypes());
resolveDataLink(PrometheusDataResource.DATAINFO_OWNER, myData.getTransactions());
/* Set the value */
setValue(pValues.getValue(PrometheusDataResource.DATAINFO_VALUE));
/* Resolve any link value */
resolveLink(null);
/* Access the TransactionInfoSet and register this data */
final MoneyWiseTransInfoSet mySet = getOwner().getInfoSet();
mySet.registerInfo(this);
} catch (OceanusException e) {
/* Pass on exception */
throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
}
}
@Override
public MetisFieldSetDef getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public MoneyWiseTransInfoType getInfoType() {
return getValues().getValue(PrometheusDataResource.DATAINFO_TYPE, MoneyWiseTransInfoType.class);
}
@Override
public MoneyWiseTransInfoClass getInfoClass() {
return getInfoType().getInfoClass();
}
@Override
public MoneyWiseTransaction getOwner() {
return getValues().getValue(PrometheusDataResource.DATAINFO_OWNER, MoneyWiseTransaction.class);
}
/**
* Obtain Deposit.
*
* @return the Deposit
*/
public MoneyWiseTransAsset getTransAsset() {
return getValues().getValue(PrometheusDataResource.DATAINFO_LINK, MoneyWiseTransAsset.class);
}
/**
* Obtain Transaction Tag.
*
* @return the Transaction Tag
*/
public MoneyWiseTransTag getTransactionTag() {
return getValues().getValue(PrometheusDataResource.DATAINFO_LINK, MoneyWiseTransTag.class);
}
@Override
public String getLinkName() {
final PrometheusDataItem myItem = getLink();
if (myItem instanceof MoneyWiseDeposit myDeposit) {
return myDeposit.getName();
}
if (myItem instanceof MoneyWisePortfolio myPortfolio) {
return myPortfolio.getName();
}
if (myItem instanceof MoneyWiseTransTag myTag) {
return myTag.getName();
}
return null;
}
@Override
public MoneyWiseDataSet getDataSet() {
return (MoneyWiseDataSet) super.getDataSet();
}
@Override
public MoneyWiseTransInfo getBase() {
return (MoneyWiseTransInfo) super.getBase();
}
@Override
public MoneyWiseTransInfoList getList() {
return (MoneyWiseTransInfoList) super.getList();
}
@Override
public void deRegister() {
/* Access the TransactionInfoSet and register this value */
final MoneyWiseTransInfoSet mySet = getOwner().getInfoSet();
mySet.deRegisterInfo(this);
}
@Override
public void rewindInfoLinkSet() {
/* Access the TransactionInfoSet and reWind this value */
final MoneyWiseTransInfoSet mySet = getOwner().getInfoSet();
mySet.rewindInfoLinkSet(this);
}
/**
* Compare this data to another to establish sort order.
*
* @param pThat The EventInfo to compare to
* @return (-1,0,1) depending of whether this object is before, equal, or after the passed
* object in the sort order
*/
@Override
public int compareValues(final PrometheusDataItem pThat) {
/* Access item */
final MoneyWiseTransInfo myThat = (MoneyWiseTransInfo) pThat;
/* Compare basic details */
int iDiff = super.compareValues(pThat);
if (iDiff != 0) {
return iDiff;
}
/* If this is a linkSet */
final MoneyWiseTransInfoType myType = myThat.getInfoType();
if (myType.getInfoClass().isLinkSet()) {
/* Compare names */
iDiff = MetisDataDifference.compareObject(getLinkName(), myThat.getLinkName());
}
return iDiff;
}
@Override
public void resolveDataSetLinks() throws OceanusException {
/* Update the Encryption details */
super.resolveDataSetLinks();
/* Resolve data links */
final MoneyWiseDataSet myData = getDataSet();
resolveDataLink(PrometheusDataResource.DATAINFO_TYPE, myData.getTransInfoTypes());
resolveDataLink(PrometheusDataResource.DATAINFO_OWNER, myData.getTransactions());
/* Resolve any link value */
resolveLink(null);
/* Access the TransactionInfoSet and register this data */
final MoneyWiseTransInfoSet mySet = getOwner().getInfoSet();
mySet.registerInfo(this);
}
/**
* resolve editSet links.
*
* @param pEditSet the edit set
* @throws OceanusException on error
*/
public void resolveEditSetLinks(final PrometheusEditSet pEditSet) throws OceanusException {
/* Update the Encryption details */
super.resolveDataSetLinks();
/* Resolve data links */
resolveDataLink(PrometheusDataResource.DATAINFO_TYPE, pEditSet.getDataList(MoneyWiseStaticDataType.TRANSINFOTYPE, MoneyWiseTransInfoTypeList.class));
resolveDataLink(PrometheusDataResource.DATAINFO_OWNER, pEditSet.getDataList(MoneyWiseBasicDataType.TRANSACTION, MoneyWiseTransactionList.class));
/* Resolve any link value */
resolveLink(pEditSet);
}
/**
* Resolve link reference.
*
* @param pEditSet the edit set
* @throws OceanusException on error
*/
private void resolveLink(final PrometheusEditSet pEditSet) throws OceanusException {
/* If we have a link */
final MoneyWiseTransInfoType myType = getInfoType();
if (myType.isLink()) {
/* Access data */
final MoneyWiseDataSet myData = getDataSet();
final Object myLinkId = getValues().getValue(PrometheusDataResource.DATAINFO_VALUE);
/* Switch on link type */
switch (myType.getInfoClass()) {
case RETURNEDCASHACCOUNT:
getOwner().resolveTransactionAsset(pEditSet == null ? getDataSet() : pEditSet, this, PrometheusDataResource.DATAINFO_LINK);
if (myLinkId == null) {
setValueValue(getTransAsset().getExternalId());
}
break;
case TRANSTAG:
resolveDataLink(PrometheusDataResource.DATAINFO_LINK, pEditSet == null
? myData.getTransactionTags()
: pEditSet.getDataList(MoneyWiseBasicDataType.TRANSTAG, MoneyWiseTransTagList.class));
if (myLinkId == null) {
setValueValue(getTransactionTag().getIndexedId());
}
break;
default:
break;
}
}
}
/**
* Update transactionInfo from a transactionInfo extract.
*
* @param pTransInfo the changed transInfo
* @return whether changes have been made
*/
@Override
public boolean applyChanges(final PrometheusDataItem pTransInfo) {
/* Can only update from TransactionInfo */
if (!(pTransInfo instanceof MoneyWiseTransInfo)) {
return false;
}
/* Access as TransactionInfo */
final MoneyWiseTransInfo myTransInfo = (MoneyWiseTransInfo) pTransInfo;
/* Store the current detail into history */
pushHistory();
/* Update the value if required */
if (!MetisDataDifference.isEqual(getField(), myTransInfo.getField())) {
setValueValue(myTransInfo.getField());
if (getInfoType().isLink()) {
setValueLink(myTransInfo.getLink());
}
}
/* Check for changes */
return checkForHistory();
}
@Override
public void touchUnderlyingItems() {
/* touch info class */
super.touchUnderlyingItems();
/* Switch on info class */
switch (getInfoClass()) {
case RETURNEDCASHACCOUNT:
getTransAsset().touchItem(getOwner());
break;
case TRANSTAG:
getTransactionTag().touchItem(getOwner());
break;
default:
break;
}
}
/**
* TransactionInfoList.
*/
public static class MoneyWiseTransInfoList
extends PrometheusDataInfoList<MoneyWiseTransInfo> {
/**
* Report fields.
*/
private static final MetisFieldSet<MoneyWiseTransInfoList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseTransInfoList.class);
/**
* Construct an empty CORE list.
*
* @param pData the DataSet for the list
*/
protected MoneyWiseTransInfoList(final MoneyWiseDataSet pData) {
super(MoneyWiseTransInfo.class, pData, MoneyWiseBasicDataType.TRANSACTIONINFO, PrometheusListStyle.CORE);
}
/**
* Constructor for a cloned List.
*
* @param pSource the source List
*/
private MoneyWiseTransInfoList(final MoneyWiseTransInfoList pSource) {
super(pSource);
}
@Override
public MetisFieldSet<MoneyWiseTransInfoList> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public String listName() {
return LIST_NAME;
}
@Override
public MetisFieldSetDef getItemFields() {
return MoneyWiseTransInfo.FIELD_DEFS;
}
@Override
public MoneyWiseDataSet getDataSet() {
return (MoneyWiseDataSet) super.getDataSet();
}
/**
* Set base list for Edit InfoList.
*
* @param pBase the base list
*/
protected void setBase(final MoneyWiseTransInfoList pBase) {
/* Set the style and base */
setStyle(PrometheusListStyle.EDIT);
super.setBase(pBase);
}
@Override
public MoneyWiseTransInfoList getEmptyList(final PrometheusListStyle pStyle) {
final MoneyWiseTransInfoList myList = new MoneyWiseTransInfoList(this);
myList.setStyle(pStyle);
return myList;
}
@Override
public MoneyWiseTransInfo addCopyItem(final PrometheusDataItem pItem) {
/* Can only clone a TransactionInfo */
if (!(pItem instanceof MoneyWiseTransInfo)) {
throw new UnsupportedOperationException();
}
final MoneyWiseTransInfo myInfo = new MoneyWiseTransInfo(this, (MoneyWiseTransInfo) pItem);
add(myInfo);
return myInfo;
}
@Override
public MoneyWiseTransInfo addNewItem() {
throw new UnsupportedOperationException();
}
@Override
protected MoneyWiseTransInfo addNewItem(final PrometheusDataItem pOwner,
final PrometheusStaticDataItem pInfoType) {
/* Allocate the new entry and add to list */
final MoneyWiseTransInfo myInfo = new MoneyWiseTransInfo(this, (MoneyWiseTransaction) pOwner, (MoneyWiseTransInfoType) pInfoType);
add(myInfo);
/* return it */
return myInfo;
}
@Override
public void addInfoItem(final Integer pId,
final PrometheusDataItem pTransaction,
final PrometheusDataInfoClass pInfoClass,
final Object pValue) throws OceanusException {
/* Ignore item if it is null */
if (pValue == null) {
return;
}
/* Access the data set */
final MoneyWiseDataSet myData = getDataSet();
/* Look up the Info Type */
final MoneyWiseTransInfoType myInfoType = myData.getTransInfoTypes().findItemByClass(pInfoClass);
if (myInfoType == null) {
throw new MoneyWiseDataException(pTransaction, ERROR_BADINFOCLASS + " [" + pInfoClass + "]");
}
/* Create the values */
final PrometheusDataValues myValues = new PrometheusDataValues(OBJECT_NAME);
myValues.addValue(MetisDataResource.DATA_ID, pId);
myValues.addValue(PrometheusDataResource.DATAINFO_TYPE, myInfoType);
myValues.addValue(PrometheusDataResource.DATAINFO_OWNER, pTransaction);
myValues.addValue(PrometheusDataResource.DATAINFO_VALUE, pValue);
/* Create a new Transaction Info */
final MoneyWiseTransInfo myInfo = new MoneyWiseTransInfo(this, myValues);
/* Check that this InfoTypeId has not been previously added */
if (!isIdUnique(myInfo.getIndexedId())) {
myInfo.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
throw new MoneyWiseDataException(myInfo, ERROR_VALIDATION);
}
/* Add the Event Info to the list */
add(myInfo);
}
@Override
public MoneyWiseTransInfo addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
/* Create the info */
final MoneyWiseTransInfo myInfo = new MoneyWiseTransInfo(this, pValues);
/* Check that this InfoId has not been previously added */
if (!isIdUnique(myInfo.getIndexedId())) {
myInfo.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
throw new MoneyWiseDataException(myInfo, ERROR_VALIDATION);
}
/* Add to the list */
add(myInfo);
/* Return it */
return myInfo;
}
/**
* Resolve ValueLinks.
*
* @throws OceanusException on error
*/
public void resolveValueLinks() throws OceanusException {
/* Loop through the Info items */
final Iterator<MoneyWiseTransInfo> myIterator = iterator();
while (myIterator.hasNext()) {
final MoneyWiseTransInfo myCurr = myIterator.next();
/* If this is an infoItem */
if (myCurr.getInfoType().isLink()) {
/* Resolve the link */
myCurr.resolveLink(null);
}
}
}
@Override
public void postProcessOnLoad() throws OceanusException {
/* Validate the TransactionInfo */
validateOnLoad();
/* Validate the Transactions */
final MoneyWiseTransactionList myTrans = getDataSet().getTransactions();
myTrans.validateOnLoad();
}
}
}