Module: Recurify::RuleTranslation

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

Overview

:nodoc:

Constant Summary collapse

NORMALIZATION_MATRIX =
{
  # Normalization is a no-op for base-frequencies ...
  'daily' =>     { target_frequency: 'daily',   interval_multiplier:  1 },
  'monthly' =>   { target_frequency: 'monthly', interval_multiplier:  1 },
  # But, it is more interesting for sugar-frequencies ...
  'weekly' =>    { target_frequency: 'daily',   interval_multiplier:  7 },
  'quarterly' => { target_frequency: 'monthly', interval_multiplier:  3 },
  'yearly' =>    { target_frequency: 'monthly', interval_multiplier: 12 }
}.freeze
DENORMALIZATION_MATRIX =
{
  'daily' => [
    # Applicable denormalizitions ordered by decreasing preferability ...
    { target_frequency: 'weekly',    interval_divisor:  7 },
    { target_frequency: 'daily',     interval_divisor:  1 }
  ],
  'weekly' => [
    # Applicable denormalizitions ordered by decreasing preferability ...
    { target_frequency: 'weekly',    interval_divisor:  1 }
  ],
  'monthly' => [
    # Applicable denormalizitions ordered by decreasing preferability ...
    { target_frequency: 'yearly',    interval_divisor: 12 },
    { target_frequency: 'quarterly', interval_divisor:  3 },
    { target_frequency: 'monthly',   interval_divisor:  1 }
  ],
  'quarterly' => [
    # Applicable denormalizitions ordered by decreasing preferability ...
    { target_frequency: 'yearly',    interval_divisor:  4 },
    { target_frequency: 'quarterly', interval_divisor:  1 }
  ],
  'yearly' => [
    # Applicable denormalizitions ordered by decreasing preferability ...
    { 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.

Denormalizion 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 #denormalize at all? The idea is that denormalized Rules are easier to parse for humans. For instance, “every 7th week” is easier to understand than “every 49th day”.

Returns:



108
109
110
111
112
113
114
115
116
117
# File 'lib/recurify/rule_translation.rb', line 108

def denormalize
  @_denormalized_rule ||= begin
    translate_with = find_best_denormalization

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

#denormalized_countFixnum?

Returns:

See Also:



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

def_delegator :denormalize, :count, :denormalized_count

#denormalized_ends_onDate?



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

def_delegator :denormalize, :ends_on, :denormalized_ends_on

#denormalized_frequencyString



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

def_delegator :denormalize, :frequency, :denormalized_frequency

#denormalized_intervalFixnum



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

def_delegator :denormalize, :interval, :denormalized_interval

#normalizeRule

TODO:

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

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

Normalization 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:



58
59
60
61
62
63
64
65
66
67
# File 'lib/recurify/rule_translation.rb', line 58

def normalize
  @_normalized_rule ||= begin
    translate_with = NORMALIZATION_MATRIX[frequency]

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

#normalized_countFixnum?

Returns:

See Also:



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

def_delegator :normalize, :count, :normalized_count

#normalized_ends_onDate?

Returns:

See Also:



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

def_delegator :normalize, :ends_on, :normalized_ends_on

#normalized_frequencyString



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

def_delegator :normalize, :frequency, :normalized_frequency

#normalized_intervalFixnum

Returns:

See Also:



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

def_delegator :normalize, :interval, :normalized_interval