Class WhittakerTech::Midas::Coin::Allocation ¶
Inherits: Object
Allocation represents a per-unit interpretation of a Coin.
Conceptual model¶
Coin -> canonical, payable money (what exists) Allocation -> "this
Coin, spread across N units, using policy X"
An Allocation answers two questions:
- What does one unit cost? —
#value - What does a given quantity cost? —
#price
Immutability¶
Allocation is:
* immutable — @coin, @divisor, and @rounding_policy are frozen on
construction and never mutated.
* not persisted — Allocation is a pure value object.
* minor-unit safe — it never stores sub-minor-unit amounts; rounding is
applied before returning a Coin.
See also: Coin#allocate
- @since 0.1.0
@example Per-unit price from a bulk price
bulk = Coin.value(10_000, 'USD') # $100.00 for a pack of 6
alloc = bulk.allocate(per: 6, rounding_policy: :ceil)
alloc.value # => Coin($16.67)
alloc.price(qty: 2) # => Coin($33.34)
Attributes¶
coin [R] ¶
- @return [Coin] the total monetary amount this Allocation is based on
- @since 0.1.0
divisor [R] ¶
- @return [Numeric] the number of units the coin covers (the divisor)
- @since 0.1.0
rounding_policy [R] ¶
- @return [Symbol] the rounding policy applied to per-unit calculations
- @since 0.1.0
Public Instance Methods¶
initialize(coin:, divisor:, rounding_policy:) ¶
- @param
coin[Coin] the total monetary value - @param
divisor[Numeric] the number of units; must be positive - @param
rounding_policy[Symbol] one ofWhittakerTech::Midas::ROUNDING_POLICIES - @raise [TypeError] if
coinis not aCoin - @raise [TypeError] if
divisoris not a positive Numeric - @raise [ArgumentError] if
rounding_policyis not a recognised policy key - @return [Allocation] a new instance of Allocation
- @since 0.1.0
inspect() ¶
Human-readable representation for logs and console output. - @return [String] - @since 0.1.0
price(qty: = 1) ¶
Returns the total price for a given quantity of units.
Uses (total_minor * qty) / divisor rounded via
#rounding_policy. Equivalent to qty units at the per-unit rate,
but computed from the original total to minimise accumulated rounding error.
- @param qty [Numeric] the number of units; must be >= 0
- @raise [ArgumentError] if qty is negative or not Numeric
- @return [Coin]
- @since 0.1.0
@example
alloc = Coin.value(10_000, 'USD').allocate(per: 6)
alloc.price(qty: 3) # => Coin($50.00) (10000 * 3 / 6 = 5000 cents)
value() ¶
Returns the per-unit Coin after dividing by #divisor and applying
the #rounding_policy.
The result is still a Coin — payable money representing a single unit.
- @return [Coin]
- @since 0.1.0