Class: ActsAsCalculator::SupersedeFormulaVersions

Inherits:
Object
  • Object
show all
Defined in:
lib/acts_as_calculator/supersede_formula_versions.rb

Overview

Makes room for a new active version. FormulaVersion refuses two active versions whose effective ranges overlap, so publishing a correction to a rule that is currently in force has to close the incumbent out first — by moving its effective_to or retiring it, never by touching its expression, which is what stays immutable.

An incumbent is only ever superseded into a range the newcomer takes over. Where the newcomer would leave part of the incumbent's range with no rule at all, this raises: effective_from is immutable on an active version, so there is no way to keep just the tail, and quietly retiring the whole row would delete coverage a past calculation had. Same principle as the resolver's "no covering version raises, never fall back" — a gap the operator did not ask for is not this Decree's to create (docs/PLAN.md, "Data model").

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(formula:, effective_from:, effective_to: nil) ⇒ SupersedeFormulaVersions

Returns a new instance of SupersedeFormulaVersions.



20
21
22
23
24
# File 'lib/acts_as_calculator/supersede_formula_versions.rb', line 20

def initialize(formula:, effective_from:, effective_to: nil)
  @formula = formula
  @effective_from = CastDate.(effective_from)
  @effective_to = effective_to && CastDate.(effective_to)
end

Class Method Details

.callObject



16
17
18
# File 'lib/acts_as_calculator/supersede_formula_versions.rb', line 16

def self.call(...)
  new(...).call
end

Instance Method Details

#callObject

Every incumbent is checked before any is written, so a refusal never leaves half the supersede applied.



28
29
30
31
32
33
34
# File 'lib/acts_as_calculator/supersede_formula_versions.rb', line 28

def call
  incumbents = overlapping
  orphaned = incumbents.find { |version| !covers_tail_of?(version) }
  raise PartialSupersedeError, uncovered_tail_message(orphaned) if orphaned

  incumbents.each { |version| supersede(version) }
end