Sha256: 4d894d60e750090e86a2711eec4e5ff4fa8bd0c0fb816dd5c9b6636a37959d78

Contents?: true

Size: 1.99 KB

Versions: 11

Compression:

Stored size: 1.99 KB

Contents

module Spree
  # A value object to hold a map of variants to their quantities
  class StockQuantities
    attr_reader :quantities
    include Enumerable

    # @param quantities [Hash<Spree::Variant=>Numeric>]
    def initialize(quantities = {})
      raise ArgumentError unless quantities.keys.all?{ |v| v.is_a?(Spree::Variant) }
      raise ArgumentError unless quantities.values.all?{ |v| v.is_a?(Numeric) }

      @quantities = quantities
    end

    # @yield [variant, quantity]
    def each(&block)
      @quantities.each(&block)
    end

    # @param variant [Spree::Variant]
    # @return [Integer] the quantity of variant
    def [](variant)
      @quantities[variant]
    end

    # @return [Array<Spree::Variant>] the variants being tracked
    def variants
      @quantities.keys.uniq
    end

    # Adds two StockQuantities together
    # @return [Spree::StockQuantities]
    def +(other)
      combine_with(other) do |_variant, a, b|
        (a || 0) + (b || 0)
      end
    end

    # Subtracts another StockQuantities from this one
    # @return [Spree::StockQuantities]
    def -(other)
      combine_with(other) do |_variant, a, b|
        (a || 0) - (b || 0)
      end
    end

    # Finds the intersection or common subset of two StockQuantities: the
    # stock which exists in both StockQuantities.
    # @return [Spree::StockQuantities]
    def &(other)
      combine_with(other) do |_variant, a, b|
        next unless a && b
        [a, b].min
      end
    end

    # A StockQuantities is empty if all variants have zero quantity
    # @return [true,false]
    def empty?
      @quantities.values.all?(&:zero?)
    end

    def ==(other)
      self.class == other.class &&
        quantities == other.quantities
    end

    protected

    def combine_with(other)
      self.class.new(
        (variants | other.variants).map do |variant|
          a = self[variant]
          b = other[variant]
          value = yield variant, a, b
          [variant, value]
        end.to_h.compact
      )
    end
  end
end

Version data entries

11 entries across 11 versions & 1 rubygems

Version Path
solidus_core-2.5.2 app/models/spree/stock_quantities.rb
solidus_core-2.5.1 app/models/spree/stock_quantities.rb
solidus_core-2.5.0 app/models/spree/stock_quantities.rb
solidus_core-2.5.0.rc1 app/models/spree/stock_quantities.rb
solidus_core-2.5.0.beta2 app/models/spree/stock_quantities.rb
solidus_core-2.5.0.beta1 app/models/spree/stock_quantities.rb
solidus_core-2.4.2 app/models/spree/stock_quantities.rb
solidus_core-2.4.1 app/models/spree/stock_quantities.rb
solidus_core-2.4.0 app/models/spree/stock_quantities.rb
solidus_core-2.4.0.rc1 app/models/spree/stock_quantities.rb
solidus_core-2.4.0.beta1 app/models/spree/stock_quantities.rb