package co.smartreceipts.android.model.factory; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import co.smartreceipts.android.model.Price; import co.smartreceipts.android.model.PriceCurrency; import co.smartreceipts.android.model.Priceable; import co.smartreceipts.android.model.gson.ExchangeRate; import co.smartreceipts.android.model.impl.ImmutableLegacyNetPriceImpl; import co.smartreceipts.android.model.impl.ImmutableNetPriceImpl; import co.smartreceipts.android.model.impl.ImmutablePriceImpl; import co.smartreceipts.android.model.impl.LegacyTripPriceImpl; import co.smartreceipts.android.model.utils.ModelUtils; /** * A {@link co.smartreceipts.android.model.Price} {@link BuilderFactory} * implementation, which will be used to generate instances of {@link co.smartreceipts.android.model.Price} objects */ public final class PriceBuilderFactory implements BuilderFactory<Price> { private BigDecimal priceDecimal; private ExchangeRate exchangeRate; private PriceCurrency currency; private List<Priceable> priceables; private List<Price> prices; private int decimalPrecision = Price.DEFAULT_DECIMAL_PRECISION; @NonNull public PriceBuilderFactory setPrice(Price price) { priceDecimal = price.getPrice(); currency = price.getCurrency(); exchangeRate = price.getExchangeRate(); return this; } @NonNull public PriceBuilderFactory setPrice(String price) { priceDecimal = ModelUtils.tryParse(price); return this; } @NonNull public PriceBuilderFactory setPrice(double price) { priceDecimal = new BigDecimal(price); return this; } @NonNull public PriceBuilderFactory setPrice(BigDecimal price) { priceDecimal = price; return this; } @NonNull public PriceBuilderFactory setCurrency(PriceCurrency currency) { this.currency = currency; return this; } @NonNull public PriceBuilderFactory setCurrency(String currencyCode) { currency = PriceCurrency.getInstance(currencyCode); return this; } @NonNull public PriceBuilderFactory setExchangeRate(ExchangeRate exchangeRate) { this.exchangeRate = exchangeRate; return this; } @NonNull public PriceBuilderFactory setPrices(@NonNull List<? extends Price> prices, @Nullable PriceCurrency desiredCurrency) { this.prices = new ArrayList<>(prices); currency = desiredCurrency; return this; } @NonNull public PriceBuilderFactory setPriceables(@NonNull List<? extends Priceable> priceables, @Nullable PriceCurrency desiredCurrency) { this.priceables = new ArrayList<>(priceables); currency = desiredCurrency; return this; } @NonNull public PriceBuilderFactory setDecimalPrecision(int decimalPrecision) { this.decimalPrecision = decimalPrecision; return this; } @NonNull @Override public Price build() { if (prices != null && !prices.isEmpty()) { if (currency != null) { return new ImmutableNetPriceImpl(currency, prices); } else { return new ImmutableLegacyNetPriceImpl(prices); } } else if (priceables != null && !priceables.isEmpty()) { final int size = priceables.size(); final ArrayList<Price> actualPrices = new ArrayList<>(size); for (int i = 0; i < size; i++) { actualPrices.add(priceables.get(i).getPrice()); } if (currency != null) { return new ImmutableNetPriceImpl(currency, actualPrices); } else { return new ImmutableLegacyNetPriceImpl(actualPrices); } } else { final BigDecimal price = priceDecimal != null ? priceDecimal : new BigDecimal(0); if (currency != null) { if (exchangeRate != null) { return new ImmutablePriceImpl(price, currency, exchangeRate, decimalPrecision); } else { return new ImmutablePriceImpl(price, currency, new ExchangeRateBuilderFactory().setBaseCurrency(currency).build(), decimalPrecision); } } else { return new LegacyTripPriceImpl(price, null); } } } }