class CoinSync::Importers::BitBay20

Constants

MAX_TIME_DIFFERENCE
OP_FEE
OP_PAY_BUYING
OP_PAY_SELLING
OP_PURCHASE
OP_SALE
TRANSACTION_TYPES

Public Instance Methods

read_transaction_list(source) click to toggle source
# File lib/coinsync/importers/bitbay20.rb, line 61
def read_transaction_list(source)
  csv = CSV.new(source, col_sep: ';')

  matching = []
  transactions = []

  csv.each do |line|
    next if line.empty?
    next if line[0] !~ /^\d/

    entry = HistoryEntry.new(line)

    next unless TRANSACTION_TYPES.include?(entry.type)

    if !matching.empty? && matching.any? { |e| (e.date - entry.date).abs > MAX_TIME_DIFFERENCE }
      if matching.any? { |e| e.type != OP_FEE }
        raise "BitBay importer error: Couldn't match some history lines"
      else
        matching.clear
      end
    end

    matching << entry

    if matching.length == 3
      matching.sort_by!(&:type)
      types = matching.map(&:type)
      time = matching.map(&:date).sort.last

      if types == [OP_PURCHASE, OP_PAY_BUYING, OP_FEE] &&
        matching[0].crypto? && matching[0].amount > 0 &&
        matching[1].fiat? && matching[1].amount < 0 &&
        matching[2].crypto? && matching[2].amount <= 0 &&
        matching[0].currency == matching[2].currency
          transactions << Transaction.new(
            exchange: 'BitBay',
            bought_currency: matching[0].currency,
            sold_currency: matching[1].currency,
            time: time,
            bought_amount: matching[0].amount + matching[2].amount,
            sold_amount: -matching[1].amount
          )
      elsif types == [OP_SALE, OP_PAY_SELLING, OP_FEE] &&
        matching[0].crypto? && matching[0].amount < 0 &&
        matching[1].fiat? && matching[1].amount > 0 &&
        matching[2].fiat? && matching[2].amount <= 0 &&
        matching[1].currency == matching[2].currency
          transactions << Transaction.new(
            exchange: 'BitBay',
            bought_currency: matching[1].currency,
            sold_currency: matching[0].currency,
            time: time,
            bought_amount: matching[1].amount + matching[2].amount,
            sold_amount: -matching[0].amount
          )
      elsif types == [OP_PURCHASE, OP_SALE, OP_FEE] &&
        matching[0].fiat? && matching[0].amount > 0 &&
        matching[1].crypto? && matching[1].amount < 0 &&
        matching[2].fiat? && matching[2].amount <= 0 &&
        matching[0].currency == matching[2].currency
          transactions << Transaction.new(
            exchange: 'BitBay',
            bought_currency: matching[0].currency,
            sold_currency: matching[1].currency,
            time: time,
            bought_amount: matching[0].amount + matching[2].amount,
            sold_amount: -matching[1].amount
          )
      else
        raise "BitBay importer error: Couldn't match some history lines"
      end

      matching.clear
    end
  end

  if !matching.empty?
    if matching.any? { |l| l.type != OP_FEE }
      raise "BitBay importer error: Couldn't match some history lines"
    end
  end

  transactions.reverse
end