module Eco::API::UseCases::GraphQL::Helpers::Location module Base include Eco::API::UseCases::GraphQL::Helpers::Base TAGTREE_BACKUP = 'cache/tagtree.json'.freeze attr_reader :current_tree attr_accessor :previous_tree # Back-up the tree everytime that it is retrieved anew. def current_tree=(value) return current_tree if current_tree == value @current_tree = value backup_tree(current_tree) value end # At any moment we want to know how the live tree is # @note it also does a backup # @return [Eco::API::Organization::TagTree] the latest tree (`current_tree`) def track_current_tree(tree) return if simulate? return unless tree latest_tree = tree if tree.is_a?(Eco::API::Organization::TagTree) if tree.respond_to?(:treeify) args = { enviro: session.enviro, id: tree.id, name: tree.name} latest_tree ||= Eco::API::Organization::TagTree.new(tree.treeify, **args) end latest_tree.tap do |_tree| next unless latest_tree @previous_tree = @current_tree self.current_tree = latest_tree end end # @param tree [Eco::API::Organization::TagTree, Hash, Array] # @return [Boolean] whether or not the backup was created def backup_tree(tree = current_tree || live_tree) return false if simulate? case tree when Eco::API::Organization::TagTree tagtree = tree.source when Hash, Array # that's allright else log(:error) { "Can't back up tagtree. Expecting TagTree, Hash or Array. Given: #{tree.class}" } return false end file = session.file_manager.save_json(tree, self.class::TAGTREE_BACKUP, :timestamp) logger.debug("Backed up tagtree saved locally to #{file}.") true end def tagtree_id %i[target_structure_id tagtree_id structure_id].find {|key| options.dig(:source, key)} end # Scopes the target structure `id`. # @note it is basic that the `id` is correctly identified. def target_structure_id @target_structure_id ||= tagtree_id @target_structure_id ||= self.class.const_get(:TARGET_STRUCTURE_ID) if self.class.const_defined?(:TARGET_STRUCTURE_ID) @target_structure_id ||= current_tree.id if current_tree.respond_to?(:id) return @target_structure_id if @target_structure_id msg = "Const TARGET_STRUCTURE_ID has not been defined, " msg << "nor options(:source, :structure_id). " msg << "Infering active locations structure." log(:warn) { msg } if self.current_tree = session_live_tree @target_structure_id = current_tree.id end end # Retrieves the live tree only if `current_tree` hasn't been just retrieved. # @note that `target_structure_id` can retrive the live tree (when `id` is not defined) # By checking if the current_tree changed after calling `target_structure_id` we # prevent unnecessary requests. def live_tree tree_init = current_tree target_id = target_structure_id return current_tree if current_tree != tree_init self.current_tree = session_live_tree(id: target_id) end # Unique access point to retrieve the live tree # @note ensures archived nodes are retrieved. def session_live_tree(id: nil) session.live_tree(id: id, include_archived: true) end end end