MoneyWiseCurrency.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.statics;
import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionValues;
import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataSet;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataClass;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
import java.util.Currency;
/**
* AssetCurrency data type.
*
* @author Tony Washer
*/
public class MoneyWiseCurrency
extends PrometheusStaticDataItem {
/**
* Object name.
*/
public static final String OBJECT_NAME = MoneyWiseStaticDataType.CURRENCY.getItemName();
/**
* List name.
*/
public static final String LIST_NAME = MoneyWiseStaticDataType.CURRENCY.getListName();
/**
* Report fields.
*/
private static final MetisFieldVersionedSet<MoneyWiseCurrency> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseCurrency.class);
/*
* FieldIds.
*/
static {
FIELD_DEFS.declareBooleanField(MoneyWiseStaticResource.CURRENCY_REPORTING);
}
/**
* Copy Constructor.
*
* @param pList The list to associate the Account Currency with
* @param pCurrency The Account Currency to copy
*/
protected MoneyWiseCurrency(final MoneyWiseCurrencyList pList,
final MoneyWiseCurrency pCurrency) {
super(pList, pCurrency);
}
/**
* Basic constructor.
*
* @param pList The list to associate the Account Currency with
* @param pName Name of Account Currency
* @throws OceanusException on error
*/
private MoneyWiseCurrency(final MoneyWiseCurrencyList pList,
final String pName) throws OceanusException {
super(pList, pName);
setValueReporting(Boolean.FALSE);
setValueEnabled(Boolean.TRUE);
setValueDesc(getCurrencyClass().getCurrency().getDisplayName());
}
/**
* Basic constructor.
*
* @param pList The list to associate the Account Currency with
* @param pClass Class of Account Currency
* @throws OceanusException on error
*/
private MoneyWiseCurrency(final MoneyWiseCurrencyList pList,
final MoneyWiseCurrencyClass pClass) throws OceanusException {
super(pList, pClass);
setValueReporting(Boolean.FALSE);
setValueEnabled(Boolean.TRUE);
setValueDesc(pClass.getCurrency().getDisplayName());
}
/**
* Values constructor.
*
* @param pList The list to associate the item with
* @param pValues the values
* @throws OceanusException on error
*/
private MoneyWiseCurrency(final MoneyWiseCurrencyList pList,
final PrometheusDataValues pValues) throws OceanusException {
super(pList, pValues);
/* Store the Default */
final Object myValue = pValues.getValue(MoneyWiseStaticResource.CURRENCY_REPORTING);
if (myValue instanceof Boolean b) {
setValueReporting(b);
} else if (myValue instanceof String s) {
final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
setValueReporting(myFormatter.parseValue(s, Boolean.class));
} else {
setValueReporting(Boolean.FALSE);
}
}
@Override
public MetisFieldSetDef getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public boolean includeXmlField(final MetisDataFieldId pField) {
/* Determine whether fields should be included */
if (MoneyWiseStaticResource.CURRENCY_REPORTING.equals(pField)) {
return true;
}
/* Pass call on */
return super.includeXmlField(pField);
}
/**
* Is this the reporting currency.
*
* @return true/false
*/
public Boolean isReporting() {
return getValues().getValue(MoneyWiseStaticResource.CURRENCY_REPORTING, Boolean.class);
}
/**
* Set reporting indication.
*
* @param pValue the value
*/
private void setValueReporting(final Boolean pValue) {
getValues().setUncheckedValue(MoneyWiseStaticResource.CURRENCY_REPORTING, pValue);
}
/**
* Return the Currency class of the AccountCurrency.
*
* @return the class
*/
public MoneyWiseCurrencyClass getCurrencyClass() {
return (MoneyWiseCurrencyClass) super.getStaticClass();
}
@Override
public MoneyWiseCurrency getBase() {
return (MoneyWiseCurrency) super.getBase();
}
@Override
public MoneyWiseCurrencyList getList() {
return (MoneyWiseCurrencyList) super.getList();
}
/**
* Return the Currency of the AccountCurrency.
*
* @return the currency
*/
public Currency getCurrency() {
return getCurrencyClass().getCurrency();
}
@Override
public int compareValues(final PrometheusDataItem pThat) {
/* Handle differences in default value */
final MoneyWiseCurrency myThat = (MoneyWiseCurrency) pThat;
if (!isReporting().equals(myThat.isReporting())) {
return Boolean.TRUE.equals(isReporting())
? -1
: 1;
}
/* Handle normally */
return super.compareValues(pThat);
}
@Override
public void resolveDataSetLinks() throws OceanusException {
/* Update the Encryption details */
super.resolveDataSetLinks();
/* Access Relevant lists */
final MetisFieldVersionValues myValues = getValues();
/* Adjust Default */
final Object myReporting = myValues.getValue(MoneyWiseStaticResource.CURRENCY_REPORTING);
if (myReporting == null) {
setValueReporting(Boolean.FALSE);
}
}
/**
* Set reporting indication.
*
* @param pReporting the new indication
*/
public void setReporting(final Boolean pReporting) {
setValueReporting(pReporting);
}
@Override
public boolean applyChanges(final PrometheusDataItem pData) {
/* Can only apply changes for AccountCurrency */
if (!(pData instanceof MoneyWiseCurrency)) {
return false;
}
/* Access the data */
final MoneyWiseCurrency myData = (MoneyWiseCurrency) pData;
/* Store the current detail into history */
pushHistory();
/* Apply basic changes */
applyBasicChanges(myData);
/* Update the reporting indication if required */
if (!isReporting().equals(myData.isReporting())) {
setReporting(myData.isReporting());
}
/* Check for changes */
return checkForHistory();
}
/**
* Represents a list of {@link MoneyWiseCurrency} objects.
*/
public static class MoneyWiseCurrencyList
extends PrometheusStaticList<MoneyWiseCurrency> {
/**
* Report fields.
*/
private static final MetisFieldSet<MoneyWiseCurrencyList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseCurrencyList.class);
/**
* Construct an empty CORE account currency list.
*
* @param pData the DataSet for the list
*/
public MoneyWiseCurrencyList(final PrometheusDataSet pData) {
super(MoneyWiseCurrency.class, pData, MoneyWiseStaticDataType.CURRENCY, PrometheusListStyle.CORE);
}
/**
* Constructor for a cloned List.
*
* @param pSource the source List
*/
private MoneyWiseCurrencyList(final MoneyWiseCurrencyList pSource) {
super(pSource);
}
@Override
public MetisFieldSet<MoneyWiseCurrencyList> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public String listName() {
return LIST_NAME;
}
@Override
public MetisFieldSetDef getItemFields() {
return MoneyWiseCurrency.FIELD_DEFS;
}
@Override
protected Class<MoneyWiseCurrencyClass> getEnumClass() {
return MoneyWiseCurrencyClass.class;
}
@Override
public MoneyWiseCurrencyDataMap getDataMap() {
return (MoneyWiseCurrencyDataMap) super.getDataMap();
}
@Override
protected MoneyWiseCurrencyList getEmptyList(final PrometheusListStyle pStyle) {
final MoneyWiseCurrencyList myList = new MoneyWiseCurrencyList(this);
myList.setStyle(pStyle);
return myList;
}
@Override
public MoneyWiseCurrency addCopyItem(final PrometheusDataItem pItem) {
/* Can only clone an AccountCurrency */
if (!(pItem instanceof MoneyWiseCurrency)) {
throw new UnsupportedOperationException();
}
final MoneyWiseCurrency myCurr = new MoneyWiseCurrency(this, (MoneyWiseCurrency) pItem);
add(myCurr);
return myCurr;
}
@Override
public MoneyWiseCurrency addNewItem() {
throw new UnsupportedOperationException();
}
/**
* Obtain the type of the item.
*
* @return the type of the item
*/
public String itemType() {
return LIST_NAME;
}
/**
* Add an AccountCurrency to the list.
*
* @param pCurrency the Name of the account currency
* @return the new currency
* @throws OceanusException on error
*/
public MoneyWiseCurrency addBasicItem(final String pCurrency) throws OceanusException {
/* Create a new Account Currency */
final MoneyWiseCurrency myCurr = new MoneyWiseCurrency(this, pCurrency);
/* Check that this AccountCurrencyId has not been previously added */
if (!isIdUnique(myCurr.getIndexedId())) {
myCurr.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
throw new MoneyWiseDataException(myCurr, ERROR_VALIDATION);
}
/* Add the Account Currency to the list */
add(myCurr);
return myCurr;
}
@Override
public MoneyWiseCurrency addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
/* Create the currency */
final MoneyWiseCurrency myCurrency = new MoneyWiseCurrency(this, pValues);
/* Check that this CurrencyId has not been previously added */
if (!isIdUnique(myCurrency.getIndexedId())) {
myCurrency.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
throw new MoneyWiseDataException(myCurrency, ERROR_VALIDATION);
}
/* Add to the list */
add(myCurrency);
/* Return it */
return myCurrency;
}
@Override
public void populateDefaults() throws OceanusException {
/* Initialise the reporting currency */
initialiseReporting();
/* Ensure that the list is sorted */
reSort();
}
/**
* Initialise the reporting currency.
*/
public void initialiseReporting() {
/* Determine the default currency */
final Currency myCurrency = OceanusMoney.getDefaultCurrency();
/* Find the currency in the list */
MoneyWiseCurrency myCurr = findCurrency(myCurrency);
if (myCurr == null) {
/* Default to GBP if local currency not found */
myCurr = findItemByClass(MoneyWiseCurrencyClass.GBP);
}
/* If we have a currency */
if (myCurr != null) {
/* Set it as the reporting */
myCurr.setReporting(Boolean.TRUE);
myCurr.setValueEnabled(Boolean.TRUE);
}
}
/**
* find a currency in the list.
*
* @param pCurrency the currency to find
* @return The currency
*/
public MoneyWiseCurrency findCurrency(final Currency pCurrency) {
/* Look up the currency */
final MoneyWiseCurrencyClass myClass = MoneyWiseCurrencyClass.fromCurrency(pCurrency);
return findItemByClass(myClass);
}
/**
* Find the reporting currency.
*
* @return The reporting currency
*/
public MoneyWiseCurrency findReporting() {
/* look up the reporting in the map */
final MoneyWiseCurrencyDataMap myMap = getDataMap();
return myMap == null
? null
: myMap.getReporting();
}
@Override
protected MoneyWiseCurrency newItem(final PrometheusStaticDataClass pClass) throws OceanusException {
/* Create the currency */
final MoneyWiseCurrency myCurr = new MoneyWiseCurrency(this, (MoneyWiseCurrencyClass) pClass);
/* Check that this CurrId has not been previously added */
if (!isIdUnique(myCurr.getIndexedId())) {
myCurr.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
throw new MoneyWiseDataException(myCurr, ERROR_VALIDATION);
}
/* Add to the list */
add(myCurr);
/* Return it */
return myCurr;
}
/**
* Set reporting currency.
*
* @param pCurrency the new reporting currency.
*/
public void setReportingCurrency(final MoneyWiseCurrency pCurrency) {
/* Find the reportingdefault currency */
final MoneyWiseCurrency myCurr = findReporting();
/* If we are changing the currency */
if (!pCurrency.equals(myCurr)) {
/* If we have a default value */
if (myCurr != null) {
/* Clear default value */
myCurr.pushHistory();
myCurr.setReporting(Boolean.FALSE);
}
/* Set new currency */
pCurrency.pushHistory();
pCurrency.setReporting(Boolean.TRUE);
}
}
@Override
protected MoneyWiseCurrencyDataMap allocateDataMap() {
return new MoneyWiseCurrencyDataMap();
}
}
/**
* The dataMap class.
*/
public static final class MoneyWiseCurrencyDataMap
extends PrometheusStaticDataMap<MoneyWiseCurrency> {
/**
* Report fields.
*/
private static final MetisFieldSet<MoneyWiseCurrencyDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseCurrencyDataMap.class);
/*
* Declare Fields.
*/
static {
FIELD_DEFS.declareLocalField(MoneyWiseStaticResource.CURRENCY_REPORTING, MoneyWiseCurrencyDataMap::getReporting);
}
/**
* Reporting value.
*/
private MoneyWiseCurrency theReporting;
/**
* Reporting count.
*/
private Integer theReportingCount;
/**
* Constructor.
*/
private MoneyWiseCurrencyDataMap() {
}
@Override
public MetisFieldSet<MoneyWiseCurrencyDataMap> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public String formatObject(final OceanusDataFormatter pFormatter) {
return FIELD_DEFS.getName();
}
@Override
public void resetMap() {
super.resetMap();
theReporting = null;
theReportingCount = null;
}
@Override
public void adjustForItem(final PrometheusDataItem pItem) {
/* Adjust order count */
final MoneyWiseCurrency myItem = (MoneyWiseCurrency) pItem;
if (Boolean.TRUE.equals(myItem.isReporting())) {
theReporting = myItem;
theReportingCount = theReportingCount == null
? ONE
: theReportingCount + 1;
}
/* Adjust name/order count */
super.adjustForItem(pItem);
}
/**
* find reporting currency.
*
* @return the reporting currency
*/
public MoneyWiseCurrency getReporting() {
return theReporting;
}
/**
* Check validity of report count.
*
* @return true/false
*/
public boolean validReportCount() {
return ONE.equals(theReportingCount);
}
}
}