<commit_before>package name.abuchen.portfolio.model;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.ResourceBundle;

import name.abuchen.portfolio.money.CurrencyConverter;
import name.abuchen.portfolio.money.Money;
import name.abuchen.portfolio.money.MoneyCollectors;
import name.abuchen.portfolio.money.Quote;
import name.abuchen.portfolio.money.Values;

public class PortfolioTransaction extends Transaction
{
    public enum Type
    {
        /** Records the purchase of a security. */
        BUY(true),
        /** Records the sale of a security. */
        SELL(false),
        /** Records the transfer of assets from another portfolio. */
        TRANSFER_IN(true),
        /** Records the transfer of assets to another portfolio. */
        TRANSFER_OUT(false),
        /** Records the transfer of assets into the portfolio. */
        DELIVERY_INBOUND(true),
        /** Records the transfer of assets out of a portfolio. */
        DELIVERY_OUTBOUND(false);

        private static final ResourceBundle RESOURCES = ResourceBundle.getBundle("name.abuchen.portfolio.model.labels"); //$NON-NLS-1$

        private final boolean isPurchase;

        private Type(boolean isPurchase)
        {
            this.isPurchase = isPurchase;
        }

        /**
         * True if the transaction is one of the purchase types such as buy,
         * transfer in, or an inbound delivery.
         */
        public boolean isPurchase()
        {
            return isPurchase;
        }

        /**
         * True if the transaction is one of the liquidation types such as sell,
         * transfer out, or an outbound delivery.
         */
        public boolean isLiquidation()
        {
            return !isPurchase;
        }

        @Override
        public String toString()
        {
            return RESOURCES.getString("portfolio." + name()); //$NON-NLS-1$
        }
    }

    private Type type;

    @Deprecated
    /* package */transient long fees;

    @Deprecated
    /* package */transient long taxes;

    public PortfolioTransaction()
    {
        // needed for xstream de-serialization
    }

    public PortfolioTransaction(LocalDateTime date, String currencyCode, long amount, Security security, long shares,
                    Type type, long fees, long taxes)
    {
        super(date, currencyCode, amount, security, shares, null);
        this.type = type;

        if (fees != 0)
            addUnit(new Unit(Unit.Type.FEE, Money.of(currencyCode, fees)));
        if (taxes != 0)
            addUnit(new Unit(Unit.Type.TAX, Money.of(currencyCode, taxes)));
    }

    public Type getType()
    {
        return type;
    }

    public void setType(Type type)
    {
        this.type = type;
    }

    /**
     * Returns the monetary amount in the term currency of the given currency
     * converter. If applicable, it uses the exchange rate given in the
     * transaction instead of the historic exchange rate of that day.
     */
    public Money getMonetaryAmount(CurrencyConverter converter)
    {
        if (getCurrencyCode().equals(converter.getTermCurrency()))
        {
            return getMonetaryAmount();
        }
        else if (getSecurity().getCurrencyCode().equals(converter.getTermCurrency()))
        {
            Optional<Unit> grossValue = getUnit(Unit.Type.GROSS_VALUE);

            // use exchange rate used within the transaction,
            // not the historical exchange rate
            BigDecimal exchangeRate = grossValue.isPresent() ? grossValue.get().getExchangeRate()
                            : converter.getRate(getDateTime(), getCurrencyCode()).getValue();

            return Money.of(converter.getTermCurrency(), BigDecimal.ONE.divide(exchangeRate, 10, RoundingMode.HALF_DOWN)
                            .multiply(BigDecimal.valueOf(getAmount())).setScale(0, RoundingMode.HALF_DOWN).longValue());
        }
        else
        {
            return converter.convert(getDateTime(), getMonetaryAmount());
        }
    }

    /**
     * Returns the gross value, i.e. the value excluding taxes and fees. See
     * {@link #getGrossValue()}.
     */<commit_msg>Fix calculating grossPrice in Securities Chart<commit_after>package name.abuchen.portfolio.model;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.ResourceBundle;

import name.abuchen.portfolio.money.CurrencyConverter;
import name.abuchen.portfolio.money.Money;
import name.abuchen.portfolio.money.MoneyCollectors;
import name.abuchen.portfolio.money.Quote;
import name.abuchen.portfolio.money.Values;

public class PortfolioTransaction extends Transaction
{
    public enum Type
    {
        /** Records the purchase of a security. */
        BUY(true),
        /** Records the sale of a security. */
        SELL(false),
        /** Records the transfer of assets from another portfolio. */
        TRANSFER_IN(true),
        /** Records the transfer of assets to another portfolio. */
        TRANSFER_OUT(false),
        /** Records the transfer of assets into the portfolio. */
        DELIVERY_INBOUND(true),
        /** Records the transfer of assets out of a portfolio. */
        DELIVERY_OUTBOUND(false);

        private static final ResourceBundle RESOURCES = ResourceBundle.getBundle("name.abuchen.portfolio.model.labels"); //$NON-NLS-1$

        private final boolean isPurchase;

        private Type(boolean isPurchase)
        {
            this.isPurchase = isPurchase;
        }

        /**
         * True if the transaction is one of the purchase types such as buy,
         * transfer in, or an inbound delivery.
         */
        public boolean isPurchase()
        {
            return isPurchase;
        }

        /**
         * True if the transaction is one of the liquidation types such as sell,
         * transfer out, or an outbound delivery.
         */
        public boolean isLiquidation()
        {
            return !isPurchase;
        }

        @Override
        public String toString()
        {
            return RESOURCES.getString("portfolio." + name()); //$NON-NLS-1$
        }
    }

    private Type type;

    @Deprecated
    /* package */transient long fees;

    @Deprecated
    /* package */transient long taxes;

    public PortfolioTransaction()
    {
        // needed for xstream de-serialization
    }

    public PortfolioTransaction(LocalDateTime date, String currencyCode, long amount, Security security, long shares,
                    Type type, long fees, long taxes)
    {
        super(date, currencyCode, amount, security, shares, null);
        this.type = type;

        if (fees != 0)
            addUnit(new Unit(Unit.Type.FEE, Money.of(currencyCode, fees)));
        if (taxes != 0)
            addUnit(new Unit(Unit.Type.TAX, Money.of(currencyCode, taxes)));
    }

    public Type getType()
    {
        return type;
    }

    public void setType(Type type)
    {
        this.type = type;
    }

    /**
     * Returns the monetary amount in the term currency of the given currency
     * converter. If applicable, it uses the exchange rate given in the
     * transaction instead of the historic exchange rate of that day.
     */
    public Money getMonetaryAmount(CurrencyConverter converter)
    {
        if (getCurrencyCode().equals(converter.getTermCurrency()))
        {
            return getMonetaryAmount();
        }
        else if (getSecurity().getCurrencyCode().equals(converter.getTermCurrency()))
        {
            Optional<Unit> grossValue = getUnit(Unit.Type.GROSS_VALUE);

            // use exchange rate used within the transaction,
            // not the historical exchange rate
            BigDecimal exchangeRate = grossValue.isPresent() ? grossValue.get().getExchangeRate()
                            : converter.getRate(getDateTime(), getCurrencyCode()).getValue();

            return Money.of(converter.getTermCurrency(), BigDecimal.ONE.divide(exchangeRate, 10, RoundingMode.HALF_DOWN)
                            .multiply(BigDecimal.valueOf(getAmount())).setScale(0, RoundingMode.HALF_DOWN).longValue());
        }
        else
        {
            return converter.convert(getDateTime(), getMonetaryAmount());
        }
    }

    /**
     * Returns the gross value, i.e. the value before taxes and fees are
     * applied. In the case of a buy transaction, that are the gross costs, i.e.
     * before adding additional taxes and fees. In the case of sell
     * transactions, that are the gross proceeds before the deduction of taxes
     * and fees. See {@link #getGrossValue()}.
     */
{'fraction_non_alphanumeric': 0.094791070406411, 'fraction_numerical': 0.0016027475672581567, 'mean_word_length': 2.251209527353926, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7593356', 'n_tokens_mistral': 2373, 'n_tokens_neox': 2282, 'n_words': 668}