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.



184
185
186
187
188
189
190
191
192
# File 'lib/checkoff/timelines.rb', line 184

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

Parameters:

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

Returns:

  • (Boolean)


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
135
136
137
138
139
140
141
# File 'lib/checkoff/timelines.rb', line 106

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
  # @type [Array<Hash{String => Object}>]
  memberships = task.memberships
  memberships.all? do |membership_data|
    # @type [Hash{String => Object}]
    md = membership_data
    unless limit_to_portfolio_name.nil?
      # @type [Hash{String => Object}]
      project_data = md.fetch('project')
      project_gid = project_data.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)


146
147
148
149
150
151
152
# File 'lib/checkoff/timelines.rb', line 146

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

Parameters:

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

Returns:

  • (Boolean)


68
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
99
100
101
# File 'lib/checkoff/timelines.rb', line 68

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
  # @type [Array<Hash{String => Object}>]
  memberships = task.memberships
  memberships.all? do |membership_data|
    # @type [Hash{String => Object}]
    md = membership_data
    unless limit_to_portfolio_name.nil?
      # @type [Hash{String => Object}]
      project_data = md.fetch('project')
      project_gid = project_data.fetch('gid')
      next true unless limit_to_projects.map(&:gid).include? project_gid
    end
    # @type [Hash{String => Object}]
    section_data = md.fetch('section')
    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