diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/ArithmeticExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/ArithmeticExercises.java index c1c0b07..1886e7e 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/ArithmeticExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/ArithmeticExercises.java @@ -21,7 +21,7 @@ public class ArithmeticExercises { * @return sum of both amounts in the same currency */ public MonetaryAmount addAmounts(MonetaryAmount firstAmount, MonetaryAmount secondAmount) { - return firstAmount.add(secondAmount); + throw new UnsupportedOperationException("TODO"); } /** @@ -34,7 +34,7 @@ public class ArithmeticExercises { * @return difference after subtraction in the same currency */ public MonetaryAmount subtractAmounts(MonetaryAmount minuend, MonetaryAmount subtrahend) { - return minuend.subtract(subtrahend); + throw new UnsupportedOperationException("TODO"); } /** @@ -47,7 +47,7 @@ public class ArithmeticExercises { * @return product amount in the same currency */ public MonetaryAmount multiplyAmount(MonetaryAmount amount, int factor) { - return amount.multiply(factor); + throw new UnsupportedOperationException("TODO"); } /** @@ -60,6 +60,6 @@ public class ArithmeticExercises { * @return {@code true} if first amount is greater, otherwise {@code false} */ public boolean compareAmounts(MonetaryAmount firstAmount, MonetaryAmount secondAmount) { - return firstAmount.isGreaterThan(secondAmount); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/FormattingExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/FormattingExercises.java index 202dc81..b1fa413 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/FormattingExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/FormattingExercises.java @@ -1,9 +1,6 @@ package swiss.fihlon.workshop.money.part1; -import java.util.Locale; import javax.money.MonetaryAmount; -import javax.money.format.MonetaryAmountFormat; -import javax.money.format.MonetaryFormats; /** *
Part 1 workshop exercises for formatting monetary amounts using JSR-354.
@@ -24,7 +21,7 @@ public class FormattingExercises { * @return formatted amount string for Swiss German locale */ public String formatSwissGerman(MonetaryAmount amount) { - return format(amount, "de-CH"); + throw new UnsupportedOperationException("TODO"); } /** @@ -36,7 +33,7 @@ public class FormattingExercises { * @return formatted amount string for German locale */ public String formatGerman(MonetaryAmount amount) { - return format(amount, "de-DE"); + throw new UnsupportedOperationException("TODO"); } /** @@ -48,20 +45,6 @@ public class FormattingExercises { * @return formatted amount string for US locale */ public String formatUs(MonetaryAmount amount) { - return format(amount, "en-US"); - } - - /** - *Format the given amount using the specified locale.
- * - *Use the provided language tag to obtain a locale-specific formatter.
- * - * @param amount the amount to format - * @param languageTag IETF BCP 47 language tag (e.g. {@code de-CH}) - * @return formatted amount string - */ - private String format(MonetaryAmount amount, String languageTag) { - MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.forLanguageTag(languageTag)); - return format.format(amount); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/IntegrationExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/IntegrationExercises.java index 4d09217..9036e31 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/IntegrationExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/IntegrationExercises.java @@ -1,13 +1,5 @@ package swiss.fihlon.workshop.money.part1; -import java.util.Locale; -import javax.money.Monetary; -import javax.money.MonetaryAmount; -import javax.money.MonetaryOperator; -import javax.money.format.MonetaryAmountFormat; -import javax.money.format.MonetaryFormats; -import org.javamoney.moneta.Money; - /** *Part 1 workshop exercises for combining parsing, arithmetic, rounding, and formatting with JSR-354.
* @@ -30,24 +22,6 @@ public class IntegrationExercises { * @return formatted final price text */ public String calculateFinalPrice(String priceText) { - // setup locale and formatter - Locale swissGerman = Locale.forLanguageTag("de-CH"); - MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(swissGerman); - - // parse - MonetaryAmount price = format.parse(priceText); - - // constants - MonetaryAmount shipping = Money.of(4.95, "CHF"); - MonetaryAmount discount = Money.of(2.00, "CHF"); - - // calculate - MonetaryAmount total = price.add(shipping).subtract(discount); - - // round - MonetaryAmount roundedTotal = total.with(Monetary.getDefaultRounding()); - - // format - return format.format(roundedTotal); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/MoneyExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/MoneyExercises.java index 28d6ddf..e63510e 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/MoneyExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/MoneyExercises.java @@ -1,9 +1,6 @@ package swiss.fihlon.workshop.money.part1; -import org.javamoney.moneta.Money; - import javax.money.CurrencyUnit; -import javax.money.Monetary; import javax.money.MonetaryAmount; /** @@ -22,7 +19,7 @@ public class MoneyExercises { * @return Swiss franc currency unit ({@code CHF}) */ public CurrencyUnit createSwissFranc() { - return Monetary.getCurrency("CHF"); + throw new UnsupportedOperationException("TODO"); } /** @@ -32,7 +29,7 @@ public class MoneyExercises { * @return monetary amount {@code 19.95 CHF} */ public MonetaryAmount createSwissFrancAmount() { - return Money.of(19.95, "CHF"); + throw new UnsupportedOperationException("TODO"); } /** @@ -42,7 +39,7 @@ public class MoneyExercises { * @return monetary amount {@code 2500 JPY} */ public MonetaryAmount createJapaneseYenAmount() { - return Money.of(2500, "JPY"); + throw new UnsupportedOperationException("TODO"); } /** @@ -52,6 +49,6 @@ public class MoneyExercises { * @return monetary amount {@code 12.345 TND} */ public MonetaryAmount createTunisianDinarAmount() { - return Money.of(12.345, "TND"); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/ParsingExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/ParsingExercises.java index cb77428..301c76a 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/ParsingExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/ParsingExercises.java @@ -1,9 +1,6 @@ package swiss.fihlon.workshop.money.part1; import javax.money.MonetaryAmount; -import javax.money.format.MonetaryAmountFormat; -import javax.money.format.MonetaryFormats; -import javax.money.format.MonetaryParseException; import java.util.Locale; /** @@ -27,7 +24,7 @@ public class ParsingExercises { * @return parsed monetary amount */ public MonetaryAmount parseSwissGerman(String text) { - return parse(text, "de-CH"); + throw new UnsupportedOperationException("TODO"); } /** @@ -39,7 +36,7 @@ public class ParsingExercises { * @return parsed monetary amount */ public MonetaryAmount parseGerman(String text) { - return parse(text, "de-DE"); + throw new UnsupportedOperationException("TODO"); } /** @@ -51,22 +48,7 @@ public class ParsingExercises { * @return parsed monetary amount */ public MonetaryAmount parseUs(String text) { - return parse(text, "en-US"); - } - - /** - *Parse the given monetary amount text using the specified locale.
- * - *Use the provided language tag to obtain a locale-specific parser.
- * - * @param text the input text to parse - * @param languageTag IETF BCP 47 language tag (e.g. {@code de-CH}) - * @return parsed monetary amount - */ - private MonetaryAmount parse(String text, String languageTag) { - MonetaryAmountFormat format = - MonetaryFormats.getAmountFormat(Locale.forLanguageTag(languageTag)); - return format.parse(text); + throw new UnsupportedOperationException("TODO"); } /** @@ -79,12 +61,6 @@ public class ParsingExercises { * @return {@code true} if parsing succeeds, otherwise {@code false} */ public boolean parseInvalidInput(String text, Locale locale) { - MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(locale); - try { - format.parse(text); - return true; - } catch (MonetaryParseException exception) { - return false; - } + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part1/RoundingExercises.java b/src/main/java/swiss/fihlon/workshop/money/part1/RoundingExercises.java index 3e81ccf..ac299e8 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part1/RoundingExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part1/RoundingExercises.java @@ -1,8 +1,6 @@ package swiss.fihlon.workshop.money.part1; -import javax.money.Monetary; import javax.money.MonetaryAmount; -import javax.money.MonetaryOperator; /** *Part 1 workshop exercises for currency-aware rounding with JSR-354.
@@ -22,7 +20,7 @@ public class RoundingExercises { * @return rounded amount */ public MonetaryAmount applyDefaultRounding(MonetaryAmount amount) { - return amount.with(Monetary.getDefaultRounding()); + throw new UnsupportedOperationException("TODO"); } /** @@ -35,7 +33,6 @@ public class RoundingExercises { * @return divided and rounded amount */ public MonetaryAmount divideAndRound(MonetaryAmount amount, int divisor) { - return amount.divide(divisor) - .with(Monetary.getDefaultRounding()); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercises.java b/src/main/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercises.java index 2173271..945040b 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercises.java @@ -2,7 +2,6 @@ package swiss.fihlon.workshop.money.part2; import javax.money.MonetaryAmount; import javax.money.convert.CurrencyConversion; -import javax.money.convert.MonetaryConversions; /** *Part 2 workshop exercises for currency conversion using JSR-354.
@@ -21,7 +20,7 @@ public class CurrencyConversionExercises { * @return currency conversion to EUR */ public CurrencyConversion getEurConversion() { - return MonetaryConversions.getConversion("EUR", "ECB"); + throw new UnsupportedOperationException("TODO"); } /** @@ -33,7 +32,6 @@ public class CurrencyConversionExercises { * @return converted amount in EUR */ public MonetaryAmount convertChfToEur(MonetaryAmount amount) { - CurrencyConversion conversion = getEurConversion(); - return amount.with(conversion); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryContextExercises.java b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryContextExercises.java index eef2f2e..395a7be 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryContextExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryContextExercises.java @@ -22,7 +22,7 @@ public class MonetaryContextExercises { * @return monetary context of the amount */ public MonetaryContext getMonetaryContext(MonetaryAmount amount) { - return amount.getContext(); + throw new UnsupportedOperationException("TODO"); } /** @@ -34,7 +34,7 @@ public class MonetaryContextExercises { * @return maximum scale from the monetary context */ public int getMaxScale(MonetaryAmount amount) { - return amount.getContext().getMaxScale(); + throw new UnsupportedOperationException("TODO"); } /** @@ -47,7 +47,7 @@ public class MonetaryContextExercises { * @return {@code true} if both contexts are equal, otherwise {@code false} */ public boolean compareContexts(MonetaryAmount firstAmount, MonetaryAmount secondAmount) { - return firstAmount.getContext().equals(secondAmount.getContext()); + throw new UnsupportedOperationException("TODO"); } /** @@ -59,7 +59,6 @@ public class MonetaryContextExercises { * @return formatted context description */ public String describeContext(MonetaryAmount amount) { - MonetaryContext context = amount.getContext(); - return "precision=" + context.getPrecision() + ", maxScale=" + context.getMaxScale(); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryOperatorExercises.java b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryOperatorExercises.java index c2b9e30..3147e8f 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryOperatorExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryOperatorExercises.java @@ -1,13 +1,14 @@ package swiss.fihlon.workshop.money.part2; -import java.math.BigDecimal; import javax.money.MonetaryAmount; import javax.money.MonetaryOperator; /** *Part 2 workshop exercises for encapsulating domain logic with MonetaryOperator.
* - *The examples focus on applying reusable monetary operations such as discounts and VAT.
+ *The exercises focus on applying reusable monetary operations such as discounts and VAT.
+ * + *The methods are intentionally incomplete and should be implemented by making tests pass.
*/ public class MonetaryOperatorExercises { @@ -20,8 +21,7 @@ public class MonetaryOperatorExercises { * @return discounted amount */ public MonetaryAmount applyDiscount(MonetaryAmount amount) { - MonetaryOperator discount = createDiscountOperator(); - return amount.with(discount); + throw new UnsupportedOperationException("TODO"); } /** @@ -33,8 +33,7 @@ public class MonetaryOperatorExercises { * @return amount after VAT */ public MonetaryAmount applyVat(MonetaryAmount amount) { - MonetaryOperator vat = createVatOperator(); - return amount.with(vat); + throw new UnsupportedOperationException("TODO"); } /** @@ -46,18 +45,7 @@ public class MonetaryOperatorExercises { * @return amount after discount and VAT */ public MonetaryAmount applyDiscountThenVat(MonetaryAmount amount) { - MonetaryOperator discount = createDiscountOperator(); - MonetaryOperator vat = createVatOperator(); - return amount.with(discount).with(vat); - } - - /** - *Create a reusable 7.7% VAT monetary operator.
- * - * @return a reusable VAT operator - */ - public MonetaryOperator createVatOperator() { - return monetaryAmount -> monetaryAmount.multiply(new BigDecimal("1.077")); + throw new UnsupportedOperationException("TODO"); } /** @@ -68,6 +56,6 @@ public class MonetaryOperatorExercises { * @return reusable discount operator */ public MonetaryOperator createDiscountOperator() { - return monetaryAmount -> monetaryAmount.multiply(new BigDecimal("0.90")); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryQueryExercises.java b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryQueryExercises.java index 3a89380..79d3d76 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryQueryExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part2/MonetaryQueryExercises.java @@ -7,7 +7,9 @@ import javax.money.MonetaryQuery; /** *Part 2 workshop exercises for extracting information from monetary amounts with MonetaryQuery.
* - *The examples focus on encapsulating reusable query logic for monetary values and currencies.
+ *The exercises focus on encapsulating reusable query logic for monetary values and currencies.
+ * + *The methods are intentionally incomplete and should be implemented by making tests pass.
*/ public class MonetaryQueryExercises { @@ -20,7 +22,7 @@ public class MonetaryQueryExercises { * @return currency code */ public String queryCurrencyCode(MonetaryAmount amount) { - return amount.query(createCurrencyCodeQuery()); + throw new UnsupportedOperationException("TODO"); } /** @@ -32,9 +34,7 @@ public class MonetaryQueryExercises { * @return default fraction digits of the currency */ public int queryDefaultFractionDigits(MonetaryAmount amount) { - MonetaryQueryPart 2 workshop examples for applying different rounding strategies with JSR-354.
+ *Part 2 workshop exercises for applying different rounding strategies with JSR-354.
* - *The examples focus on treating rounding as an explicit domain decision that depends on the use case.
+ *The exercises focus on treating rounding as an explicit domain decision that depends on the use case.
+ * + *The methods are intentionally incomplete and should be implemented by making tests pass.
*/ public class RoundingStrategyExercises { @@ -22,8 +21,7 @@ public class RoundingStrategyExercises { * @return amount rounded with default currency rounding */ public MonetaryAmount applyDefaultRounding(MonetaryAmount amount) { - MonetaryOperator rounding = Monetary.getDefaultRounding(); - return amount.with(rounding); + throw new UnsupportedOperationException("TODO"); } /** @@ -35,8 +33,7 @@ public class RoundingStrategyExercises { * @return CHF amount rounded to the nearest 0.05 */ public MonetaryAmount applySwissCashRounding(MonetaryAmount amount) { - MonetaryOperator swissCashRounding = createSwissCashRounding(); - return amount.with(swissCashRounding); + throw new UnsupportedOperationException("TODO"); } /** @@ -47,19 +44,6 @@ public class RoundingStrategyExercises { * @return reusable Swiss cash rounding operator */ public MonetaryOperator createSwissCashRounding() { - return monetaryAmount -> { - if (!"CHF".equals(monetaryAmount.getCurrency().getCurrencyCode())) { - throw new IllegalArgumentException("Swiss cash rounding only supports CHF."); - } - - BigDecimal increment = new BigDecimal("0.05"); - BigDecimal value = monetaryAmount.getNumber().numberValueExact(BigDecimal.class); - BigDecimal rounded = value.divide(increment, 0, RoundingMode.HALF_UP).multiply(increment); - - return monetaryAmount.getFactory() - .setCurrency(monetaryAmount.getCurrency()) - .setNumber(rounded) - .create(); - }; + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part3/OrderExercises.java b/src/main/java/swiss/fihlon/workshop/money/part3/OrderExercises.java index 549cb6f..3ada081 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part3/OrderExercises.java +++ b/src/main/java/swiss/fihlon/workshop/money/part3/OrderExercises.java @@ -1,19 +1,14 @@ package swiss.fihlon.workshop.money.part3; -import java.math.BigDecimal; -import java.util.Locale; import javax.money.CurrencyUnit; -import javax.money.Monetary; import javax.money.MonetaryAmount; -import javax.money.MonetaryOperator; -import javax.money.convert.MonetaryConversions; -import javax.money.format.MonetaryAmountFormat; -import javax.money.format.MonetaryFormats; /** - *Part 3 workshop examples for integrating monetary calculations into a small order workflow.
+ *Part 3 workshop exercises for integrating monetary calculations into a small order workflow.
* - *The examples focus on combining subtotal calculation, discount, VAT, rounding, and formatting.
+ *The exercises focus on combining subtotal calculation, discount, VAT, rounding, and formatting.
+ * + *The methods are intentionally incomplete and should be implemented by making tests pass.
*/ public class OrderExercises { @@ -27,7 +22,7 @@ public class OrderExercises { * @return subtotal amount */ public MonetaryAmount calculateSubtotal(MonetaryAmount unitPrice, int quantity) { - return unitPrice.multiply(quantity); + throw new UnsupportedOperationException("TODO"); } /** @@ -39,8 +34,7 @@ public class OrderExercises { * @return discounted amount */ public MonetaryAmount applyDiscount(MonetaryAmount subtotal) { - MonetaryOperator discount = amount -> amount.multiply(new BigDecimal("0.90")); - return subtotal.with(discount); + throw new UnsupportedOperationException("TODO"); } /** @@ -52,9 +46,7 @@ public class OrderExercises { * @return VAT-inclusive amount */ public MonetaryAmount applyVat(MonetaryAmount discountedAmount) { - MonetaryAmount vatInclusiveAmount = discountedAmount.multiply(new BigDecimal("1.077")); - MonetaryOperator rounding = Monetary.getDefaultRounding(); - return vatInclusiveAmount.with(rounding); + throw new UnsupportedOperationException("TODO"); } /** @@ -67,9 +59,7 @@ public class OrderExercises { * @return final total amount */ public MonetaryAmount calculateTotal(MonetaryAmount unitPrice, int quantity) { - MonetaryAmount subtotal = calculateSubtotal(unitPrice, quantity); - MonetaryAmount discountedAmount = applyDiscount(subtotal); - return applyVat(discountedAmount); + throw new UnsupportedOperationException("TODO"); } /** @@ -81,8 +71,7 @@ public class OrderExercises { * @return formatted total string */ public String formatTotal(MonetaryAmount total) { - MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.forLanguageTag("de-CH")); - return format.format(total); + throw new UnsupportedOperationException("TODO"); } /** @@ -95,6 +84,6 @@ public class OrderExercises { * @return amount converted to the target currency */ public MonetaryAmount convertToCurrency(MonetaryAmount amount, CurrencyUnit targetCurrency) { - return amount.with(MonetaryConversions.getConversion(targetCurrency, "ECB")); + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part4/CsvExchangeRateProvider.java b/src/main/java/swiss/fihlon/workshop/money/part4/CsvExchangeRateProvider.java index d508689..005f3e4 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part4/CsvExchangeRateProvider.java +++ b/src/main/java/swiss/fihlon/workshop/money/part4/CsvExchangeRateProvider.java @@ -1,30 +1,18 @@ package swiss.fihlon.workshop.money.part4; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; import javax.money.convert.ConversionQuery; -import javax.money.convert.ConversionContext; -import javax.money.convert.ConversionContextBuilder; import javax.money.convert.CurrencyConversion; import javax.money.convert.ExchangeRate; import javax.money.convert.ExchangeRateProvider; import javax.money.convert.ProviderContext; -import javax.money.convert.ProviderContextBuilder; -import javax.money.convert.RateType; -import org.javamoney.moneta.convert.ExchangeRateBuilder; -import org.javamoney.moneta.spi.DefaultNumberValue; -import org.javamoney.moneta.spi.LazyBoundCurrencyConversion; /** *Bonus exercise 1 for implementing a local CSV-based exchange rate provider with JSR-354.
* *The provider is intended for workshop usage and should read rates from the classpath resource * {@code exchange-rates.csv}.
+ * + *The implementation is intentionally incomplete and should be finished by making tests pass.
*/ public class CsvExchangeRateProvider implements ExchangeRateProvider { @@ -32,10 +20,6 @@ public class CsvExchangeRateProvider implements ExchangeRateProvider { *Name of the classpath CSV resource containing exchange rates.
*/ public static final String RESOURCE_NAME = "exchange-rates.csv"; - private static final ProviderContext CONTEXT = - ProviderContextBuilder.of("csv-exchange-rate-provider", RateType.HISTORIC).build(); - - private final MapCreate a new provider instance.
@@ -43,7 +27,6 @@ public class CsvExchangeRateProvider implements ExchangeRateProvider { *The provider should load exchange rates from {@link #RESOURCE_NAME}.
*/ public CsvExchangeRateProvider() { - this.ratesByPair = loadRates(); } /** @@ -53,7 +36,7 @@ public class CsvExchangeRateProvider implements ExchangeRateProvider { */ @Override public ProviderContext getContext() { - return CONTEXT; + throw new UnsupportedOperationException("TODO"); } /** @@ -64,16 +47,7 @@ public class CsvExchangeRateProvider implements ExchangeRateProvider { */ @Override public ExchangeRate getExchangeRate(ConversionQuery conversionQuery) { - CurrencyPair currencyPair = CurrencyPair.from(conversionQuery); - BigDecimal factor = ratesByPair.get(currencyPair); - if (factor == null) { - return null; - } - return new ExchangeRateBuilder(getContext().getProviderName(), RateType.DEFERRED) - .setBase(conversionQuery.getBaseCurrency()) - .setTerm(conversionQuery.getCurrency()) - .setFactor(DefaultNumberValue.of(factor)) - .build(); + throw new UnsupportedOperationException("TODO"); } /** @@ -86,60 +60,6 @@ public class CsvExchangeRateProvider implements ExchangeRateProvider { */ @Override public CurrencyConversion getCurrencyConversion(ConversionQuery conversionQuery) { - if (getExchangeRate(conversionQuery) == null) { - return null; - } - ConversionContext conversionContext = ConversionContextBuilder.create(getContext(), RateType.DEFERRED).build(); - return new LazyBoundCurrencyConversion(conversionQuery, this, conversionContext); - } - - /** - *Load exchange rates from the classpath CSV resource into a lookup map.
- * - *The CSV is expected to contain a header and records in the format - * {@code base,term,rate}.
- * - * @return map keyed by currency pair containing the configured exchange factor - */ - private static MapSimple key for identifying an exchange rate by base and term currency code.
- * - * @param baseCurrencyCode ISO currency code of the base currency - * @param termCurrencyCode ISO currency code of the term currency - */ - private record CurrencyPair(String baseCurrencyCode, String termCurrencyCode) { - /** - *Create a currency-pair key from a conversion query.
- * - * @param conversionQuery query containing base and term currency - * @return key for map-based rate lookup - */ - private static CurrencyPair from(ConversionQuery conversionQuery) { - return new CurrencyPair( - conversionQuery.getBaseCurrency().getCurrencyCode(), - conversionQuery.getCurrency().getCurrencyCode()); - } + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part4/CsvHistoricalExchangeRateProvider.java b/src/main/java/swiss/fihlon/workshop/money/part4/CsvHistoricalExchangeRateProvider.java index 802bd1f..320bbaa 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part4/CsvHistoricalExchangeRateProvider.java +++ b/src/main/java/swiss/fihlon/workshop/money/part4/CsvHistoricalExchangeRateProvider.java @@ -1,27 +1,11 @@ package swiss.fihlon.workshop.money.part4; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigDecimal; import java.time.LocalDate; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TreeMap; import javax.money.convert.ConversionQuery; -import javax.money.convert.ConversionContext; -import javax.money.convert.ConversionContextBuilder; import javax.money.convert.CurrencyConversion; import javax.money.convert.ExchangeRate; import javax.money.convert.ExchangeRateProvider; import javax.money.convert.ProviderContext; -import javax.money.convert.ProviderContextBuilder; -import javax.money.convert.RateType; -import org.javamoney.moneta.convert.ExchangeRateBuilder; -import org.javamoney.moneta.spi.DefaultNumberValue; -import org.javamoney.moneta.spi.LazyBoundCurrencyConversion; /** *Bonus exercise 2 for implementing a local CSV-based historical exchange rate provider with JSR-354.
@@ -30,6 +14,8 @@ import org.javamoney.moneta.spi.LazyBoundCurrencyConversion; * {@code exchange-rates-hist.csv}. * *The lookup should use base currency, term currency, and a date passed in the query context.
+ * + *The implementation is intentionally incomplete and should be finished by making tests pass.
*/ public class CsvHistoricalExchangeRateProvider implements ExchangeRateProvider { @@ -42,10 +28,6 @@ public class CsvHistoricalExchangeRateProvider implements ExchangeRateProvider { *Query key type for historical lookups.
*/ public static final ClassCreate a new provider instance.
@@ -53,7 +35,6 @@ public class CsvHistoricalExchangeRateProvider implements ExchangeRateProvider { *The provider should load exchange rates from {@link #RESOURCE_NAME}.
*/ public CsvHistoricalExchangeRateProvider() { - this.ratesByPairAndDate = loadRates(); } /** @@ -63,7 +44,7 @@ public class CsvHistoricalExchangeRateProvider implements ExchangeRateProvider { */ @Override public ProviderContext getContext() { - return CONTEXT; + throw new UnsupportedOperationException("TODO"); } /** @@ -81,27 +62,7 @@ public class CsvHistoricalExchangeRateProvider implements ExchangeRateProvider { */ @Override public ExchangeRate getExchangeRate(ConversionQuery conversionQuery) { - LocalDate requestedDate = conversionQuery.get(DATE_QUERY_KEY); - if (requestedDate == null) { - return null; - } - - CurrencyPair currencyPair = CurrencyPair.from(conversionQuery); - NavigableMapLoad historical exchange rates from the classpath CSV resource into a date-indexed lookup map.
- * - *The CSV is expected to contain a header and records in the format - * {@code date,base,term,rate}.
- * - * @return map keyed by currency pair with a navigable date-to-rate mapping - */ - private static MapSimple key for identifying a historical exchange-rate series by base and term currency code.
- * - * @param baseCurrencyCode ISO currency code of the base currency - * @param termCurrencyCode ISO currency code of the term currency - */ - private record CurrencyPair(String baseCurrencyCode, String termCurrencyCode) { - /** - *Create a currency-pair key from a conversion query.
- * - * @param conversionQuery query containing base and term currency - * @return key for map-based historical rate lookup - */ - private static CurrencyPair from(ConversionQuery conversionQuery) { - return new CurrencyPair( - conversionQuery.getBaseCurrency().getCurrencyCode(), - conversionQuery.getCurrency().getCurrencyCode()); - } + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/main/java/swiss/fihlon/workshop/money/part4/DukePointsExchangeRateProvider.java b/src/main/java/swiss/fihlon/workshop/money/part4/DukePointsExchangeRateProvider.java index 2d4c7c6..0dadb80 100644 --- a/src/main/java/swiss/fihlon/workshop/money/part4/DukePointsExchangeRateProvider.java +++ b/src/main/java/swiss/fihlon/workshop/money/part4/DukePointsExchangeRateProvider.java @@ -1,32 +1,20 @@ package swiss.fihlon.workshop.money.part4; -import java.math.BigDecimal; import javax.money.convert.ConversionQuery; -import javax.money.convert.ConversionContext; -import javax.money.convert.ConversionContextBuilder; import javax.money.convert.CurrencyConversion; import javax.money.convert.ExchangeRate; import javax.money.convert.ExchangeRateProvider; import javax.money.convert.ProviderContext; -import javax.money.convert.ProviderContextBuilder; -import javax.money.convert.RateType; -import org.javamoney.moneta.convert.ExchangeRateBuilder; -import org.javamoney.moneta.spi.DefaultNumberValue; -import org.javamoney.moneta.spi.LazyBoundCurrencyConversion; /** *Bonus exercise 3 for implementing local exchange rates between CHF and DukePoints.
* *The provider should support deterministic conversion for {@code CHF -> DKP} and {@code DKP -> CHF}.
+ * + *The implementation is intentionally incomplete and should be finished by making tests pass.
*/ public class DukePointsExchangeRateProvider implements ExchangeRateProvider { - private static final BigDecimal CHF_TO_DKP_FACTOR = new BigDecimal("0.1"); - private static final BigDecimal DKP_TO_CHF_FACTOR = new BigDecimal("10"); - private static final ProviderContext CONTEXT = - ProviderContextBuilder.of("dkp-exchange-rate-provider", RateType.HISTORIC).build(); - private static final String CHF = "CHF"; - /** *Create a new exchange rate provider for DukePoints.
*/ @@ -40,7 +28,7 @@ public class DukePointsExchangeRateProvider implements ExchangeRateProvider { */ @Override public ProviderContext getContext() { - return CONTEXT; + throw new UnsupportedOperationException("TODO"); } /** @@ -53,19 +41,7 @@ public class DukePointsExchangeRateProvider implements ExchangeRateProvider { */ @Override public ExchangeRate getExchangeRate(ConversionQuery conversionQuery) { - String baseCurrencyCode = conversionQuery.getBaseCurrency().getCurrencyCode(); - String termCurrencyCode = conversionQuery.getCurrency().getCurrencyCode(); - - BigDecimal factor = resolveFactor(baseCurrencyCode, termCurrencyCode); - if (factor == null) { - return null; - } - - return new ExchangeRateBuilder(getContext().getProviderName(), RateType.HISTORIC) - .setBase(conversionQuery.getBaseCurrency()) - .setTerm(conversionQuery.getCurrency()) - .setFactor(DefaultNumberValue.of(factor)) - .build(); + throw new UnsupportedOperationException("TODO"); } /** @@ -78,27 +54,6 @@ public class DukePointsExchangeRateProvider implements ExchangeRateProvider { */ @Override public CurrencyConversion getCurrencyConversion(ConversionQuery conversionQuery) { - if (getExchangeRate(conversionQuery) == null) { - return null; - } - ConversionContext conversionContext = ConversionContextBuilder.create(getContext(), RateType.HISTORIC).build(); - return new LazyBoundCurrencyConversion(conversionQuery, this, conversionContext); - } - - /** - *Resolve the conversion factor for a supported DukePoints currency pair.
- * - * @param baseCurrencyCode currency code of the base currency - * @param termCurrencyCode currency code of the target currency - * @return conversion factor for supported pairs, otherwise {@code null} - */ - private BigDecimal resolveFactor(String baseCurrencyCode, String termCurrencyCode) { - if (CHF.equals(baseCurrencyCode) && DukePointsCurrencyFactory.DKP.equals(termCurrencyCode)) { - return CHF_TO_DKP_FACTOR; - } - if (DukePointsCurrencyFactory.DKP.equals(baseCurrencyCode) && CHF.equals(termCurrencyCode)) { - return DKP_TO_CHF_FACTOR; - } - return null; + throw new UnsupportedOperationException("TODO"); } } diff --git a/src/test/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercisesTest.java b/src/test/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercisesTest.java index 1ad9a00..f563807 100644 --- a/src/test/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercisesTest.java +++ b/src/test/java/swiss/fihlon/workshop/money/part2/CurrencyConversionExercisesTest.java @@ -1,13 +1,13 @@ package swiss.fihlon.workshop.money.part2; -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.LocalDateTime; -import javax.money.MonetaryAmount; -import javax.money.convert.CurrencyConversion; import org.javamoney.moneta.Money; import org.junit.jupiter.api.Test; +import javax.money.MonetaryAmount; +import javax.money.convert.CurrencyConversion; + +import static org.assertj.core.api.Assertions.assertThat; + class CurrencyConversionExercisesTest { private final CurrencyConversionExercises exercises = new CurrencyConversionExercises(); @@ -29,25 +29,4 @@ class CurrencyConversionExercisesTest { assertThat(result).isNotNull(); assertThat(result.getCurrency().getCurrencyCode()).isEqualTo("EUR"); } - - @Test - void shouldCreateEurConversionForTimestamp() { - LocalDateTime timestamp = LocalDateTime.of(2024, 1, 15, 10, 30); - - CurrencyConversion conversion = exercises.getEurConversionForTimestamp(timestamp); - - assertThat(conversion).isNotNull(); - assertThat(conversion.getCurrency().getCurrencyCode()).isEqualTo("EUR"); - } - - @Test - void shouldConvertChfToEurAtTimestamp() { - MonetaryAmount chfAmount = Money.of(10, "CHF"); - LocalDateTime timestamp = LocalDateTime.of(2024, 1, 15, 10, 30); - - MonetaryAmount result = exercises.convertChfToEurAt(chfAmount, timestamp); - - assertThat(result).isNotNull(); - assertThat(result.getCurrency().getCurrencyCode()).isEqualTo("EUR"); - } } diff --git a/src/test/java/swiss/fihlon/workshop/money/part2/RoundingStrategyExercisesTest.java b/src/test/java/swiss/fihlon/workshop/money/part2/RoundingStrategyExercisesTest.java index 6904009..7e2c60e 100644 --- a/src/test/java/swiss/fihlon/workshop/money/part2/RoundingStrategyExercisesTest.java +++ b/src/test/java/swiss/fihlon/workshop/money/part2/RoundingStrategyExercisesTest.java @@ -1,11 +1,12 @@ package swiss.fihlon.workshop.money.part2; -import java.math.BigDecimal; -import javax.money.MonetaryAmount; -import javax.money.MonetaryOperator; import org.javamoney.moneta.Money; import org.junit.jupiter.api.Test; +import javax.money.MonetaryAmount; +import javax.money.MonetaryOperator; +import java.math.BigDecimal; + import static org.assertj.core.api.Assertions.assertThat; class RoundingStrategyExercisesTest { @@ -23,17 +24,6 @@ class RoundingStrategyExercisesTest { assertThat(result.getNumber().numberValueExact(BigDecimal.class)).isEqualByComparingTo("10.02"); } - @Test - void shouldRoundVatAmount() { - MonetaryAmount taxAmount = Money.of(1.537, "CHF"); - - MonetaryAmount result = exercises.roundVatAmount(taxAmount); - - assertThat(result).isNotNull(); - assertThat(result.getCurrency().getCurrencyCode()).isEqualTo("CHF"); - assertThat(result.getNumber().numberValueExact(BigDecimal.class)).isEqualByComparingTo("1.54"); - } - @Test void shouldApplySwissCashRounding() { MonetaryAmount firstAmount = Money.of(10.02, "CHF");