lib/eco/api/common/people/supervisor_helpers.rb in eco-helpers-2.0.15 vs lib/eco/api/common/people/supervisor_helpers.rb in eco-helpers-2.0.16
- old
+ new
@@ -13,10 +13,11 @@
module ClassMethods
# Reorders as follows:
# 1. supervisors, people with no supervisor or where their supervisor not present
# 2. subordinates
+ # @return [Array<Entry>] `values` sorted by supervisors/subordinates
def sort_by_supervisors(values, supervisors_first: true)
raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
return [] unless values && values.is_a?(Enumerable)
roam = Proc.new do |tree|
[].tap do |out|
@@ -28,9 +29,35 @@
end
end
end
roam.call(supervisors_tree(values))
+ end
+
+ # Identifies all the cyclic supervisor chains
+ # @note as `supervisors_tree` will have any entry involved in a cycle at the top, it just checks all the top entries against their offspring
+ # @return [Array<Array>] the sets of entries that are cyclic
+ def identify_cyclic_chains(values)
+ raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
+ return [] unless values && values.is_a?(Enumerable)
+
+ identify = Proc.new do |top_sup, offspring, chain = [top_sup]|
+ next [] if offspring.empty?
+ offspring.each_with_object([]) do |(sup, subordinates), set|
+ break set unless set.empty?
+ if top_sup.supervisor_id == sup.id
+ set.concat(chain, [sup])
+ else
+ set = identify.call(top_sup, subordinates, chain | [sup])
+ end
+ end
+ end
+
+ supervisors_tree(values).each_with_object([]) do |(top_sup, offspring), sets|
+ if (set = identify.call(top_sup, offspring)) && !set.empty?
+ sets.push(set)
+ end
+ end
end
def tree_to_str(tree, lev: 0)
raise "Required Hash tree structure. Given: #{tree.class}" unless tree.is_a?(Hash)
"".tap do |str|