module Ecoportal module API class V2 class Page class Stage < Ecoportal::API::Common::Content::DoubleModel passkey :id passforced :patch_ver, default: 1 passthrough :name, :ordering passarray :subtags, order_matters: false passarray :section_ids passthrough :status passboolean :complete, :lock_after_completion embeds_many :permits, klass: "Ecoportal::API::V2::Page::Permit" passboolean :disable_direct_permissions passboolean :creator_enabled, :creator_editable embeds_one :creator_flags, klass: "Ecoportal::API::V2::Page::PermissionFlags" passthrough :can def ooze self._parent.ooze end def components sections.map(&:components).flatten(1).uniq end # @yield [section] do some stuff with section. # @yieldparam section [Ecoportal::API::V2::Page::Section] one of the sections of this stage # @return [Array] sections attached to this stage. def sections sec_ids = section_ids.to_a root.sections.values_at(*sec_ids).select.with_index do |sec, i| puts "Warning: section #{id} points to missing section #{sec_ids[i]}" if !sec sec && (!block_given? || yield(sec)) end.sort_by.with_index {|sec, index| [sec.weight, index]} end # Check if a section belongs to a stage # @raise [ArgumentError] if none of the valid types of `sec_or_id` are used # @param sec_or_id [String, Ecoportal::API::V2::Page::Section] # @return [Boolean] whether or not the section belongs to the stage def section?(sec_or_id) case sec_or_id when Ecoportal::API::V2::Page::Section section?(sec_or_id.id) when String self.section_ids.include?(sec_or_id) else raise ArgumentError.new("sec_or_id must be either a Section or a String. Given: #{sec_or_id.class}") end end # Adds one or more sections to this stage # @raise [ArgumentError] if any of the elements is not a Section # @raise [Exception] if any of the sections does not belong to ooze.sections # @param secs [Array] sections to be added to this stage. def add_section(*secs) secs.each do |sec| unless sec.is_a?(Ecoportal::API::V2::Page::Section) msg = "Expected Ecoportal::API::V2::Page::Section. Given: #{sec.class}" raise ArgumentError.new(msg) end unless ooze.sections.include?(sec) msg = "The section '#{sec.heading}' (#{sec.id}) is not present in ooze.sections.\n" msg += "Review your script (i.e. @var where you store previous ooze runs)." raise msg end section_ids.insert_one(sec.id) end self end # Adds a direct permission to this stage # @note it will prevent to duplicate permits on same `user_id` # @raise [ArgumentError] if `value` is not of any of the expected classes # @param value [Ecoportal::API::Internal::Person, Hash] either the person # or the actual Hash model with String keys person `user_id`, `user_name`, `user_email` # @yieldparam section [Ecoportal::API::V2::Page::Permit] the created permit def add_permit(value, &block) props = ["user_id", "user_name", "user_email"] hash_props = case value when Ecoportal::API::Internal::Person return false unless account = value.account props.zip([account.user_id, value.name, value.email]).to_h when Hash value.slice(*props) else raise ArgumentError.new("Expected Ecoportal::API::Internal::Person or Hash. Given: #{value.class}") end hash_doc = Ecoportal::API::V2::Page::Permit.new_doc.merge(hash_props) exists = self.permits.any? {|permit| permit.user_id == hash_doc["user_id"]} return false if exists self.permits.upsert!(hash_doc, &block) end end end end end end