class Ballista::Projection

Projection class for creating journals

Public Class Methods

new(params = {}) click to toggle source
# File lib/ballista/projection.rb, line 8
def initialize(params = {})
  @entries = params[:entries]
end

Public Instance Methods

project(start_dt, end_dt) click to toggle source
# File lib/ballista/projection.rb, line 12
def project(start_dt, end_dt)
  entries = start_dt.upto(end_dt).map { |date| parse_day(date) }
  Ledger.new(entries: entries.flatten)
end

Private Instance Methods

build_actions(entry) click to toggle source
# File lib/ballista/projection.rb, line 55
def build_actions(entry)
  entry[:actions].map { |name, amount| { name: name, amount: amount } }
end
build_entry(entry, date) click to toggle source
# File lib/ballista/projection.rb, line 46
def build_entry(entry, date)
  Ledger::Entry.new(
    date: date,
    name: entry[:name],
    state: '!',
    actions: build_actions(entry)
  )
end
calendar() click to toggle source
# File lib/ballista/projection.rb, line 59
def calendar
  return @calendar if @calendar
  @calendar = Hash.new { |h, k| h[k] = [] }
  load_entries!
  @calendar
end
get_days(date) click to toggle source

This method pads all months so their last day covers through 31 This ensures all monthly events can trigger, even in shorter months

# File lib/ballista/projection.rb, line 22
def get_days(date)
  return [date.day] if date.month == date.next.month
  date.day.upto(date.day + 3).to_a
end
load_entries!() click to toggle source
# File lib/ballista/projection.rb, line 66
def load_entries!
  @entries.each do |entry|
    dates = entry[:when]
    dates = [dates] unless dates.is_a? Array
    dates.each { |date| @calendar[date] << entry }
  end
end
out_of_bounds?(entry, date) click to toggle source
# File lib/ballista/projection.rb, line 27
def out_of_bounds?(entry, date)
  if entry[:starts] && Date.parse(entry[:starts]) > date
    true
  elsif entry[:ends] && Date.parse(entry[:ends]) < date # rubocop:disable Lint/DuplicateBranch
    true
  else
    false
  end
end
parse_day(date) click to toggle source
# File lib/ballista/projection.rb, line 37
def parse_day(date)
  get_days(date).map do |fake_day|
    calendar[fake_day].map do |entry|
      next if out_of_bounds?(entry, date)
      build_entry(entry, date)
    end.compact
  end
end