All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.tinkoff.acquiring.sdk.Money Maven / Gradle / Ivy

/*
 * Copyright © 2016 Tinkoff Bank
 *
 * 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 ru.tinkoff.acquiring.sdk;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

/**
 * @author Mikhail Artemyev
 */
public class Money implements Serializable, Comparable {

    private static final byte COINS_IN_RUBLE = 100;
    private static final byte PRECISION = 2;
    public static final String DEFAULT_INT_DIVIDER = " ";
    public static final String DEFAULT_INT_FRACT_DIVIDER = ",";

    private final long valueCoins;
    private String integralDivider = DEFAULT_INT_DIVIDER;
    private String integralFractionDivider = DEFAULT_INT_FRACT_DIVIDER;

    public static Money ofRubles(final long rubles) {
        return new Money(toCoins(rubles));
    }

    public static Money ofRubles(final BigDecimal value) {
        final BigDecimal precised = value.setScale(PRECISION, RoundingMode.HALF_EVEN);
        final BigDecimal coins = precised.multiply(new BigDecimal(COINS_IN_RUBLE, new MathContext(0)));
        return new Money(coins.longValue());
    }

    public static Money ofRubles(final double rubles) {
        return ofRubles(new BigDecimal(rubles));
    }

    public static Money ofCoins(final long coins) {
        return new Money(coins);
    }

    private static long toCoins(final long rubles) {
        return rubles * COINS_IN_RUBLE;
    }

    public Money() {
        this(0L);
    }

    private Money(long valueCoins) {
        this.valueCoins = valueCoins;
    }

    public long getCoins() {
        return valueCoins;
    }

    @Override
    public String toString() {
        final long fractional = valueCoins % COINS_IN_RUBLE;

        if (fractional == 0) {
            return formatIntPart(valueCoins);
        }

        return String.format("%s%s%s",
                formatIntPart(valueCoins),
                getIntegralFractionDivider(),
                formatFractionalPart(fractional));
    }

    private String formatFractionalPart(long fractional) {
        return String.format("%02d", fractional);
    }

    public String toHumanReadableString() {
        return toString() + " P";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Money money = (Money) o;

        return valueCoins == money.valueCoins;

    }

    @Override
    public int hashCode() {
        return (int) (valueCoins ^ (valueCoins >>> 32));
    }

    public String getIntegralDivider() {
        return integralDivider;
    }

    public void setIntegralDivider(String integralDivider) {
        this.integralDivider = integralDivider;
    }

    public String getIntegralFractionDivider() {
        return integralFractionDivider;
    }

    public void setIntegralFractionDivider(String integralFractionDivider) {
        this.integralFractionDivider = integralFractionDivider;
    }

    private String formatIntPart(final long decimal) {
        if (decimal < 100) {
            return "0";
        }

        String unformatted = String.valueOf(decimal);

        // trim last digits as they are fractional part
        unformatted = unformatted.substring(0, unformatted.length() - PRECISION);

        // separate first < 3 characters as 'head'
        final int headLength = unformatted.length() % 3;
        final StringBuilder result;
        if (headLength > 0) {
            result = new StringBuilder(unformatted.substring(0, headLength));
        } else {
            result = new StringBuilder();
        }

        for (int i = headLength; i < unformatted.length(); i++) {
            final int headlessOffset = i - headLength;

            // separate each 3 characters
            if (headlessOffset % 3 == 0 && i != unformatted.length() - 1) {
                result.append(getIntegralDivider());
            }

            result.append(unformatted.charAt(i));
        }

        return result.toString();
    }

    @Override
    public int compareTo(Money o) {
        return Long.valueOf(valueCoins).compareTo(o.getCoins());
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy