Module: Recurify::RuleTranslation

Extended by:
Forwardable
Included in:
Rule
Defined in:
lib/recurify/rule_translation.rb

Overview

:nodoc:

Constant Summary collapse

FREQUENCY_MINIMIZATION_MATRIX =

Applicable frequency minimizations grouped by #frequency

{
  'daily' =>     { target_frequency: 'daily',   interval_multiplier:  1 },
  'monthly' =>   { target_frequency: 'monthly', interval_multiplier:  1 },
  'weekly' =>    { target_frequency: 'daily',   interval_multiplier:  7 },
  'quarterly' => { target_frequency: 'monthly', interval_multiplier:  3 },
  'yearly' =>    { target_frequency: 'monthly', interval_multiplier: 12 }
}.freeze
FREQUENCY_MAXIMIZATION_MATRIX =

Applicable frequency maximizations grouped by #frequency and ordered by decreasing preferability …

{
  'daily' => [
    { target_frequency: 'weekly',    interval_divisor:  7 },
    { target_frequency: 'daily',     interval_divisor:  1 }
  ],
  'weekly' => [
    { target_frequency: 'weekly',    interval_divisor:  1 }
  ],
  'monthly' => [
    { target_frequency: 'yearly',    interval_divisor: 12 },
    { target_frequency: 'quarterly', interval_divisor:  3 },
    { target_frequency: 'monthly',   interval_divisor:  1 }
  ],
  'quarterly' => [
    { target_frequency: 'yearly',    interval_divisor:  4 },
    { target_frequency: 'quarterly', interval_divisor:  1 }
  ],
  'yearly' => [
    { target_frequency: 'yearly',    interval_divisor:  1 }
  ]
}.freeze

Instance Method Summary collapse

Instance Method Details

#denormalizeRule

Creates a new Rule, similar to self, but denormalized. Note that #denormalized is idempotent.

Returns:



135
136
137
# File 'lib/recurify/rule_translation.rb', line 135

def denormalize
  @_denormalized_rule ||= maximize_frequency
end

#denormalized_attributesHash<Symbol,Object>

Returns:

  • (Hash<Symbol,Object>)

See Also:



143
# File 'lib/recurify/rule_translation.rb', line 143

def_delegator :denormalize, :attributes, :denormalized_attributes

#denormalized_countFixnum?

Returns:

  • (Fixnum, nil)

See Also:



161
# File 'lib/recurify/rule_translation.rb', line 161

def_delegator :denormalize, :count, :denormalized_count

#denormalized_ends_onDate?

Returns:

  • (Date, nil)

See Also:



167
# File 'lib/recurify/rule_translation.rb', line 167

def_delegator :denormalize, :ends_on, :denormalized_ends_on

#denormalized_frequencyString

Returns:

  • (String)

See Also:



149
# File 'lib/recurify/rule_translation.rb', line 149

def_delegator :denormalize, :frequency, :denormalized_frequency

#denormalized_intervalFixnum

Returns:

  • (Fixnum)

See Also:



155
# File 'lib/recurify/rule_translation.rb', line 155

def_delegator :denormalize, :interval, :denormalized_interval

#maximize_frequencyRule

Creates a new Rule, similar to self, but with maximized #frequency. Note that #maximize_frequency is idempotent.

Frequency maximization means that Rules with #frequency

  • … “daily” are translated to Rules with #frequency “weekly”.

  • … “monthly” are translated to Rules with #frequency “yearly”.

  • … “monthly” are translated to Rules with #frequency “quarterly”.

Additional translations may be added in the future.

Why maximize the #frequency at all? The idea is that frequency-maximized Rules are easier to parse for humans. For instance, “every 7th week” is easier to understand than “every 49th day”.

Returns:

See Also:



120
121
122
123
124
125
126
127
128
129
# File 'lib/recurify/rule_translation.rb', line 120

def maximize_frequency
  translate_with = FREQUENCY_MAXIMIZATION_MATRIX[frequency].find do |c|
    interval % c[:interval_divisor] == 0
  end

  substitute(
    frequency: translate_with[:target_frequency],
    interval:  interval / translate_with[:interval_divisor]
  )
end

#minimize_frequencyRule

Creates a new Rule, similar to self, but with minimized #frequency. Note that #minimize_frequency is idempotent.

Frequency minimization means that Rules with #frequency

  • … “weekly” are translated to Rules with #frequency “daily”.

  • … “quarterly” are translated to Rules with #frequency “monthly”.

  • … “yearly” are translated to Rules with #frequency “monthly”.

Additional translations may be added in the future.

Returns:

See Also:



53
54
55
56
57
58
59
60
# File 'lib/recurify/rule_translation.rb', line 53

def minimize_frequency
  translate_with = FREQUENCY_MINIMIZATION_MATRIX[frequency]

  substitute(
    frequency: translate_with[:target_frequency],
    interval:  interval * translate_with[:interval_multiplier]
  )
end

#normalizeRule

TODO:

This method is not yet complete, because #normalize should also minimize #ends_on and #count (if possible).

Creates a new Rule, similar to self, but normalized. Note that #normalize is idempotent.

Returns:



69
70
71
# File 'lib/recurify/rule_translation.rb', line 69

def normalize
  @_normalized_rule ||= minimize_frequency
end

#normalized_attributesHash<Symbol,Object>

Returns:

  • (Hash<Symbol,Object>)

See Also:



77
# File 'lib/recurify/rule_translation.rb', line 77

def_delegator :normalize, :attributes, :normalized_attributes

#normalized_countFixnum?

Returns:

  • (Fixnum, nil)

See Also:



95
# File 'lib/recurify/rule_translation.rb', line 95

def_delegator :normalize, :count, :normalized_count

#normalized_ends_onDate?

Returns:

  • (Date, nil)

See Also:



101
# File 'lib/recurify/rule_translation.rb', line 101

def_delegator :normalize, :ends_on, :normalized_ends_on

#normalized_frequencyString

Returns:

  • (String)

See Also:



83
# File 'lib/recurify/rule_translation.rb', line 83

def_delegator :normalize, :frequency, :normalized_frequency

#normalized_intervalFixnum

Returns:

  • (Fixnum)

See Also:



89
# File 'lib/recurify/rule_translation.rb', line 89

def_delegator :normalize, :interval, :normalized_interval