<commit_before>module Fintech
  class Stat
    attr_accessor :date, :previous, :rate, :installment, :payments, :fees_assessed

    def initialize(attrs = {})
      attrs.each { |k, v| send("#{k}=", v) if respond_to?("#{k}=") }
    end

    def payment_cents
      @payment_cents ||= payments.any? ? payments.map(&:amount_cents).reduce(:+) : 0
    end

    # principal
    def beginning_balance
      @beginning_balance ||= previous.ending_balance
    end

    def ending_balance
      @ending_balance ||= beginning_balance - principal
    end

    def principal
      @principal ||= payment_cents - fees_paid - interest_paid
    end

    def principal_due
      @principal_due ||= installment ? installment.principal : 0
    end

    def total_principal_due
      @total_principal_due ||= previous.total_principal_due + principal_due
    end

    def total_principal_paid
      @total_principal_paid ||= previous.total_principal_paid + principal
    end

    def principal_receivable
      @principal_receivable ||= total_principal_due - total_principal_paid
    end

    # interest
    def beginning_interest
      @beginning_interest ||= previous.ending_interest
    end

    def interest_paid
      @interest_paid ||= [payment_cents - fees_paid, beginning_interest].min
    end

    def interest_accrued
      @interest_accrued ||= [ending_balance, 0].max * rate.daily
    end

    def ending_interest
      @ending_interest ||= beginning_interest + interest_accrued - interest_paid
    end

    def total_interest_income
      @total_interest_income ||= previous.total_interest_income + interest_accrued
    end

    def total_interest_due
      @total_interest_due ||= installment ? previous.total_interest_income : previous.total_interest_due
    end

    def total_interest_paid
      @total_interest_paid ||= previous.total_interest_paid + interest_paid
    end

    def interest_receivable
      @interest_receivable ||= total_interest_due - total_interest_paid
    end

    # fees
    def beginning_fees
      @beginning_fees ||= previous.ending_fees
    end

    def fees_paid
      @fees_paid ||= [[beginning_fees, payment_cents].min, 0].max
    end

    def ending_fees
      @ending_fees ||= beginning_fees + fees_assessed - fees_paid
    end

    def inspect
      "<Fintech::Stat ending_balance: #{ending_balance}>"
    end
  end
end<commit_msg>add AR calculation, note for handling payments<commit_after>module Fintech
  class Stat
    attr_accessor :date, :previous, :rate, :installment, :payments, :fees_assessed

    def initialize(attrs = {})
      attrs.each { |k, v| send("#{k}=", v) if respond_to?("#{k}=") }
    end

    # TODO: Refine payment handling:
    #   for the past, use payments
    #   assume future installments will be paid
    #   adjust to prevent overpayment
    #   extend to cover remaining balance
    #   apply to future installments

    def payment_cents
      @payment_cents ||= payments.any? ? payments.map(&:amount_cents).reduce(:+) : 0
    end

    # principal
    def beginning_balance
      @beginning_balance ||= previous.ending_balance
    end

    def ending_balance
      @ending_balance ||= beginning_balance - principal
    end

    def principal
      @principal ||= payment_cents - fees_paid - interest_paid
    end

    def principal_due
      @principal_due ||= installment ? installment.principal : 0
    end

    def total_principal_due
      @total_principal_due ||= previous.total_principal_due + principal_due
    end

    def total_principal_paid
      @total_principal_paid ||= previous.total_principal_paid + principal
    end

    def principal_receivable
      @principal_receivable ||= total_principal_due - total_principal_paid
    end

    # interest
    def beginning_interest
      @beginning_interest ||= previous.ending_interest
    end

    def interest_paid
      @interest_paid ||= [payment_cents - fees_paid, beginning_interest].min
    end

    def interest_accrued
      @interest_accrued ||= [ending_balance, 0].max * rate.daily
    end

    def ending_interest
      @ending_interest ||= beginning_interest + interest_accrued - interest_paid
    end

    def total_interest_income
      @total_interest_income ||= previous.total_interest_income + interest_accrued
    end

    def total_interest_due
      @total_interest_due ||= installment ? previous.total_interest_income : previous.total_interest_due
    end

    def total_interest_paid
      @total_interest_paid ||= previous.total_interest_paid + interest_paid
    end

    def interest_receivable
      @interest_receivable ||= total_interest_due - total_interest_paid
    end

    # fees
    def beginning_fees
      @beginning_fees ||= previous.ending_fees
    end

    def fees_paid
      @fees_paid ||= [[beginning_fees, payment_cents].min, 0].max
    end

    def ending_fees
      @ending_fees ||= beginning_fees + fees_assessed - fees_paid
    end

    def accounts_receivable
      @accounts_receivable ||= principal_receivable + interest_receivable
    end

    def inspect
      "<Fintech::Stat ending_balance: #{ending_balance}>"
    end
  end
end
{'fraction_non_alphanumeric': 0.07817398119122257, 'fraction_numerical': 0.001567398119122257, 'mean_word_length': 3.18785890073831, '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': '5481326', 'n_tokens_mistral': 1607, 'n_tokens_neox': 1521, 'n_words': 343}