Module: SplttyCLI::Groups

Defined in:
lib/spltty_cli/groups.rb

Overview

Split-group helpers. A group is a name -> { participant => percentage } map, e.g. { "Thiago" => 70, "Camila" => 30 }. Percentages are integers; a group should sum to 100 (validation warns, never hard-fails — Totals normalizes by the sum anyway). Groups are resolved at settlement time by spltty totals (see Totals): a Responsible value naming a group is split by it; anything else is treated as a person.

Class Method Summary collapse

Class Method Details

.canonical(name, hash) ⇒ Object

Order-independent comparable key for a group definition: the name plus its participant=>pct pairs sorted by participant. Used to detect the same definition across ledgers for global promotion.



56
57
58
# File 'lib/spltty_cli/groups.rb', line 56

def canonical(name, hash)
  [name, hash.sort_by { |k, _| k.to_s }.map { |k, v| [k.to_s, v] }]
end

.format(hash) ⇒ Object

Human-readable one-line form: "Thiago 70, Camila 30".



28
29
30
# File 'lib/spltty_cli/groups.rb', line 28

def format(hash)
  hash.map { |name, pct| "#{name} #{pct}" }.join(", ")
end

.format_split(hash) ⇒ Object

Round-trip form accepted by parse_split: "Thiago:70,Camila:30". Used to pre-fill prompts and examples with a value the user can edit in place.



34
35
36
# File 'lib/spltty_cli/groups.rb', line 34

def format_split(hash)
  hash.map { |name, pct| "#{name}:#{pct}" }.join(",")
end

.parse_split(str) ⇒ Object

Parse "Thiago:70,Camila:30" -> { "Thiago" => 70, "Camila" => 30 }. Raises ArgumentError on malformed input.

Raises:

  • (ArgumentError)


15
16
17
18
19
20
21
22
23
24
25
# File 'lib/spltty_cli/groups.rb', line 15

def parse_split(str)
  raise ArgumentError, "empty split" if str.nil? || str.strip.empty?

  str.split(",").each_with_object({}) do |pair, h|
    name, pct = pair.split(":", 2).map(&:strip)
    raise ArgumentError, "bad split segment #{pair.inspect} (expected NAME:PCT)" if name.nil? || name.empty? || pct.nil?
    raise ArgumentError, "non-integer percentage in #{pair.inspect}" unless pct.match?(/\A\d+\z/)

    h[name] = pct.to_i
  end
end

.validate(name, hash) ⇒ Object

Warn (on $stderr) when percentages are not integers or don't sum to 100. Returns true when clean, false when a warning was emitted.



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/spltty_cli/groups.rb', line 40

def validate(name, hash)
  unless hash.is_a?(Hash) && !hash.empty? && hash.values.all? { |v| v.is_a?(Integer) }
    warn "spltty: group #{name.inspect} has non-integer or empty percentages"
    return false
  end
  sum = hash.values.sum
  if sum != 100
    warn "spltty: group #{name.inspect} percentages sum to #{sum}, not 100"
    return false
  end
  true
end