Class: Checkoff::Timelines

Inherits:
Object
  • Object
show all
Extended by:
CacheMethod::ClassMethods
Defined in:
lib/checkoff/timelines.rb

Overview

Manages timelines of dependent tasks with dates and milestones

Constant Summary collapse

MINUTE =
60
HOUR =
MINUTE * 60
DAY =
24 * HOUR
REALLY_LONG_CACHE_TIME =
HOUR * 1
LONG_CACHE_TIME =
MINUTE * 15
SHORT_CACHE_TIME =
MINUTE

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: Checkoff::Internal::ConfigLoader.load(:asana), workspaces: Checkoff::Workspaces.new(config:), sections: Checkoff::Sections.new(config:), tasks: Checkoff::Tasks.new(config:), portfolios: Checkoff::Portfolios.new(config:), clients: Checkoff::Clients.new(config:), client: clients.client) ⇒ Timelines

Returns a new instance of Timelines.

Parameters:



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/checkoff/timelines.rb', line 34

def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
               workspaces: Checkoff::Workspaces.new(config:),
               sections: Checkoff::Sections.new(config:),
               tasks: Checkoff::Tasks.new(config:),
               portfolios: Checkoff::Portfolios.new(config:),
               clients: Checkoff::Clients.new(config:),
               client: clients.client)
  @workspaces = workspaces
  @sections = sections
  @tasks = tasks
  @portfolios = portfolios
  @client = client
end

Class Method Details

.runvoid

This method returns an undefined value.



177
178
179
180
181
182
183
184
185
# File 'lib/checkoff/timelines.rb', line 177

def run
  # @type [String]
  # workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
  # @type [String]
  # timeline_name = ARGV[1] || raise('Please pass timeline name as second argument')
  # timelines = Checkoff::Timelines.new
  # timeline = timelines.timeline_or_raise(workspace_name, timeline_name)
  # puts "Results: #{timeline}"
end

Instance Method Details

#any_milestone_depends_on_this_task?(task, limit_to_portfolio_name: nil) ⇒ Boolean

@sg-ignore

Parameters:

  • task (Asana::Resources::Task)
  • limit_to_portfolio_name (String, nil) (defaults to: nil)

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/checkoff/timelines.rb', line 104

def any_milestone_depends_on_this_task?(task, limit_to_portfolio_name: nil)
  unless limit_to_portfolio_name.nil?
    limit_to_projects = @portfolios.projects_in_portfolio(@workspaces.default_workspace.name,
                                                          limit_to_portfolio_name)
  end

  all_dependent_milestones = nil
  task.memberships.all? do |membership_data|
    unless limit_to_portfolio_name.nil?
      # @sg-ignore
      project_gid = membership_data.fetch('project').fetch('gid')
      next true unless limit_to_projects.map(&:gid).include? project_gid
    end

    # do this once, but lazily, so we don't have to do it if all
    # projects are excluded
    all_dependent_milestones ||=
      @tasks.all_dependent_tasks(task,
                                 extra_task_fields: ['resource_subtype',
                                                     'memberships.project.gid']).select do |dependent_task|
        dependent_task.resource_subtype == 'milestone'
      end

    # @sg-ignore
    all_dependent_milestones.any? do |milestone|
      milestone.memberships.any? do |milestone_membership_data|
        milestone_membership_data.fetch('project').fetch('gid') == project_gid
      end
    end
  end
end

#last_milestone_in_section(section_gid) ⇒ Asana::Resources::Task?

Parameters:

  • section_gid (String)

Returns:

  • (Asana::Resources::Task, nil)


139
140
141
142
143
144
145
# File 'lib/checkoff/timelines.rb', line 139

def last_milestone_in_section(section_gid)
  # @type [Array<Asana::Resources::Task>]
  task_list = @sections.tasks_by_section_gid(section_gid,
                                             extra_fields: ['resource_subtype']).to_a
  last_task = task_list.last
  last_task&.resource_subtype == 'milestone' ? last_task : nil
end

#last_task_milestone_depends_on_this_task?(task, limit_to_portfolio_name: nil) ⇒ Boolean

@sg-ignore

Parameters:

  • task (Asana::Resources::Task)
  • limit_to_portfolio_name (String, nil) (defaults to: nil)

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/checkoff/timelines.rb', line 69

def last_task_milestone_depends_on_this_task?(task, limit_to_portfolio_name: nil)
  unless limit_to_portfolio_name.nil?
    limit_to_projects = @portfolios.projects_in_portfolio(@workspaces.default_workspace.name,
                                                          limit_to_portfolio_name)
  end

  all_dependent_task_gids = nil
  task.memberships.all? do |membership_data|
    unless limit_to_portfolio_name.nil?
      # @sg-ignore
      project_gid = membership_data.fetch('project').fetch('gid')
      next true unless limit_to_projects.map(&:gid).include? project_gid
    end
    # @sg-ignore
    section_data = membership_data.fetch('section')
    # @sg-ignore
    section_gid = section_data.fetch('gid')

    last_milestone = last_milestone_in_section(section_gid)

    next false if last_milestone.nil?

    next true if last_milestone.gid == task.gid

    all_dependent_task_gids ||= @tasks.all_dependent_tasks(task).map(&:gid)

    # @sg-ignore
    all_dependent_task_gids.include? last_milestone.gid
  end
end

#task_dependent_on_previous_section_last_milestone?(task, limit_to_portfolio_gid: nil) ⇒ Boolean

Parameters:

  • task (Asana::Resources::Task)
  • limit_to_portfolio_gid (String, nil) (defaults to: nil)

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/checkoff/timelines.rb', line 51

def task_dependent_on_previous_section_last_milestone?(task, limit_to_portfolio_gid: nil)
  task_data = @tasks.task_to_h(task)
  # @type [Array<Hash{String => Hash{String => String}}>]
  memberships_data = task_data.fetch('memberships')
  memberships_data.all? do |membership_data|
    # @type [Hash{String => String}]
    section_data = membership_data.fetch('section')
    section_gid = section_data.fetch('gid')
    section = @sections.section_by_gid(section_gid)
    # @sg-ignore
    task_data_dependent_on_previous_section_last_milestone?(task_data, section)
  end
end