spree-contrib/spree-product-assembly

View on GitHub
app/services/spree/cart/add_item_decorator.rb

Summary

Maintainability
A
35 mins
Test Coverage
module Spree::Cart::AddItemDecorator
  private

  def add_to_line_item(order:, variant:, quantity: nil, public_metadata: {}, private_metadata: {}, options: {})
    options ||= {}
    quantity ||= 1
    line_item = Spree::Dependencies.line_item_by_variant_finder.constantize.new.execute(order: order, variant: variant, options: options)
    line_item_created = line_item.nil?

    if line_item_created
      opts = ::Spree::PermittedAttributes.line_item_attributes.flatten.each_with_object({}) do |attribute, result|
        result[attribute] = options[attribute]
      end.merge(currency: order.currency).merge(whitelist(options)).delete_if { |_key, value| value.nil? }

      line_item = order.line_items.new(quantity: quantity,
                                      variant: variant,
                                      options: opts)
    else
      line_item.quantity += quantity.to_i
    end

    line_item.target_shipment = options[:shipment] if options.key? :shipment
    line_item.save!

    line_item.reload.update_price

    ::Spree::TaxRate.adjust(order, [line_item]) if line_item_created
    populate_part_line_items(line_item: line_item, options: options) if options[:populate]
    success(order: order, line_item: line_item, line_item_created: line_item_created, options: options)
  end

  def populate_part_line_items(line_item:, options:)
    parts = line_item.variant.parts_variants
    parts.each do |part|
      part_line_item = line_item.part_line_items.find_or_initialize_by(
        line_item: line_item,
        variant_id: variant_id_for(part, options)
      )

      part_line_item.update!(quantity: part.count)
    end
  end

  def part_variant_ids(line_item)
    line_item.part_line_items.map(&:variant_id)
  end

  def variant_id_for(part, options)
    if part.variant_selection_deferred?
      options[:selected_variants]['selected_variants'][part.part.id.to_s]
    else
      part.part.id
    end
  end

  def whitelist(params)
    if params.is_a? ActionController::Parameters
      params.permit(Spree::PermittedAttributes.line_item_attributes)
    else
      params.slice(*Spree::PermittedAttributes.line_item_attributes)
    end
  end
end

Spree::Cart::AddItem.prepend Spree::Cart::AddItemDecorator if Spree.version.to_f >= 3.7