Class: Smith::Budget::Ledger

Inherits:
Object
  • Object
show all
Defined in:
lib/smith/budget/ledger.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(limits: {}, consumed: {}) ⇒ Ledger

Returns a new instance of Ledger.



17
18
19
20
21
22
23
# File 'lib/smith/budget/ledger.rb', line 17

def initialize(limits: {}, consumed: {})
  @mutex = Mutex.new
  @identity = Object.new.freeze
  @reservation_contract = ReservationContract.new(ledger_identity: @identity)
  initialize_contracts(limits)
  initialize_state(consumed)
end

Instance Attribute Details

#limitsObject (readonly)

Returns the value of attribute limits.



15
16
17
# File 'lib/smith/budget/ledger.rb', line 15

def limits
  @limits
end

Instance Method Details

#consumedObject



25
26
27
# File 'lib/smith/budget/ledger.rb', line 25

def consumed
  @mutex.synchronize { @representation.externalize(@publication.state.consumed).freeze }
end

#reconcile!(reservation, actual_amount) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/smith/budget/ledger.rb', line 36

def reconcile!(reservation, actual_amount)
  amounts = @reservation_contract.amounts!(reservation)
  unless amounts.one?
    raise ArgumentError, "single-dimension reconciliation requires a single-dimension reservation"
  end

  reconcile_many!(reservation, actual: { amounts.keys.first => actual_amount }).values.first
end

#reconcile_many!(reservation, actual:) ⇒ Object



45
46
47
48
49
# File 'lib/smith/budget/ledger.rb', line 45

def reconcile_many!(reservation, actual:)
  token = @reservation_contract.token!(reservation)
  actuals = validated_amounts(actual, "actual budget")
  @mutex.synchronize { settle_reservation(token, actuals) }
end

#release!(reservation) ⇒ Object



51
52
53
54
# File 'lib/smith/budget/ledger.rb', line 51

def release!(reservation)
  released = release_many!(reservation)
  released.values.first if released.one?
end

#release_many!(reservation) ⇒ Object



56
57
58
59
# File 'lib/smith/budget/ledger.rb', line 56

def release_many!(reservation)
  token = @reservation_contract.token!(reservation)
  @mutex.synchronize { release_reservation(token) }
end

#remaining(key) ⇒ Object



61
62
63
64
65
66
67
68
# File 'lib/smith/budget/ledger.rb', line 61

def remaining(key)
  dimension = @amount_contract.dimension!(key)
  @amount_contract.known_dimension!(dimension)
  @mutex.synchronize do
    amount = @state_transition.remaining(@publication.state, dimension)
    @representation.externalize_amount(dimension, amount)
  end
end

#reserve!(key, amount) ⇒ Object



29
# File 'lib/smith/budget/ledger.rb', line 29

def reserve!(key, amount) = reserve_many!(key => amount)

#reserve_many!(reservations) ⇒ Object



31
32
33
34
# File 'lib/smith/budget/ledger.rb', line 31

def reserve_many!(reservations)
  amounts = validated_amounts(reservations, "budget reservation")
  @mutex.synchronize { create_reservation(amounts) }
end