Module: Menuconform::Rules::ConflictRules

Defined in:
lib/menuconform/rules/conflict_rules.rb

Overview

CONFLICT-001..005: statically unsatisfiable or ambiguous constraints.

Class Method Summary collapse

Class Method Details

.call(menu) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/menuconform/rules/conflict_rules.rb', line 9

def call(menu)
  out = []
  menu.groups_by_id.each_value do |g|
    out.concat(group_findings(g))
  end
  menu.each_conditional_context do |g, o, trigger|
    next unless trigger[:status] == :invalid
    out << Finding.new("CONFLICT-005", "modifier_group", g["id"],
                       "option #{o['modifier_id']} has conditional prices whose trigger " \
                       "is not a single max_select:1 group attached to the same item")
  end
  out
end

.default_findings(g, options, max, max_units) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/menuconform/rules/conflict_rules.rb', line 45

def default_findings(g, options, max, max_units)
  defaults = options.select { |o| (o["default_quantity"] || 0).positive? }
  default_units = defaults.sum { |o| o["default_quantity"] }
  problems = []
  problems << "#{defaults.size} default option(s) exceed max_select #{max}" if !max.nil? && defaults.size > max
  problems << "#{default_units} default unit(s) exceed max_total_units #{max_units}" if !max_units.nil? && default_units > max_units
  defaults.each do |o|
    mq = o["max_quantity"] || 1
    problems << "option #{o['modifier_id']} defaults to #{o['default_quantity']} but max_quantity is #{mq}" if o["default_quantity"] > mq
  end
  return [] if problems.empty?
  [Finding.new("CONFLICT-003", "modifier_group", g["id"], problems.join("; "))]
end

.group_findings(g) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/menuconform/rules/conflict_rules.rb', line 23

def group_findings(g)
  out = []
  min = g["min_select"] || 0
  max = g["max_select"]
  min_units = g["min_total_units"]
  max_units = g["max_total_units"]
  options = g["options"] || []

  if (!max.nil? && min > max) || (min_units && !max_units.nil? && min_units > max_units)
    out << Finding.new("CONFLICT-001", "modifier_group", g["id"],
                       "minimum exceeds maximum (min_select #{min} / max_select #{max.inspect}, " \
                       "min_total_units #{min_units.inspect} / max_total_units #{max_units.inspect})")
  end
  if min.positive? && options.empty?
    out << Finding.new("CONFLICT-002", "modifier_group", g["id"],
                       "requires #{min} selection(s) but offers no options")
  end
  out.concat(default_findings(g, options, max, max_units))
  out.concat(included_findings(g, max, max_units))
  out
end

.included_findings(g, max, max_units) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/menuconform/rules/conflict_rules.rb', line 59

def included_findings(g, max, max_units)
  inc = g["included_quantity"] || 0
  return [] unless inc.positive?
  cap = g["included_counting"] == "options" ? max : max_units
  return [] if cap.nil? || inc <= cap
  [Finding.new("CONFLICT-004", "modifier_group", g["id"],
               "included_quantity #{inc} exceeds the group maximum (#{cap})")]
end