Module: PredictabilityEngine::Calculators::CfdForecaster

Defined in:
lib/predictability_engine/calculators/cfd_forecaster.rb

Constant Summary collapse

DEFAULT_HISTORY_RANGE =
'2m'

Class Method Summary collapse

Class Method Details

.forecast_series(work_items, trials: 10_000, percentiles: PredictabilityEngine::DEFAULT_PERCENTILES, history_range: nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/predictability_engine/calculators/cfd_forecaster.rb', line 22

def self.forecast_series(work_items, trials: 10_000, percentiles: PredictabilityEngine::DEFAULT_PERCENTILES,
                         history_range: nil)
  cfd_data = ensure_data_up_to_today(Cfd.calculate(work_items), work_items)
  return nil if cfd_data.empty?

  summary = forecast_summary(work_items, trials: trials, percentiles: percentiles)
  return nil unless summary

  history, future_data, max_days = slice_series(cfd_data, summary, percentiles, history_range)
  { dates: build_dates(history, max_days), arrivals: build_arrivals(history, max_days, future_data),
    departed: history.map { |d| d[:departed] }, summary: summary, max_days: max_days,
    forecasts: build_forecast_map(history, summary, max_days, percentiles, future_data) }
end

.forecast_summary(work_items, trials: 10_000, percentiles: PredictabilityEngine::DEFAULT_PERCENTILES) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/predictability_engine/calculators/cfd_forecaster.rb', line 10

def self.forecast_summary(work_items, trials: 10_000, percentiles: PredictabilityEngine::DEFAULT_PERCENTILES)
  backlog = work_items.reject(&:completed?).size
  historical = Throughput.daily(work_items).values
  return nil if historical.empty?
  return nil if backlog.zero? && work_items.none? { |i| i.end_date && i.end_date > PredictabilityEngine.today }

  results = simulate_backlog(backlog, historical, trials)
  days_to_future = days_to_last_scheduled_event(work_items)

  build_summary(work_items, results, days_to_future, percentiles)
end

.future_dates(work_items, field) ⇒ Object



58
59
60
# File 'lib/predictability_engine/calculators/cfd_forecaster.rb', line 58

def self.future_dates(work_items, field)
  work_items.map { |i| i.send(field) }.compact.select { |d| d > PredictabilityEngine.today }
end