mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-14 04:04:23 +00:00
Merge pull request #10812 from Matt-Yorkley/options-values
Remove OptionValue and OptionType code
This commit is contained in:
@@ -173,8 +173,7 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
:default_price,
|
||||
:stock_locations,
|
||||
:stock_items,
|
||||
:variant_overrides,
|
||||
{ option_values: :option_type }
|
||||
:variant_overrides
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ module Admin
|
||||
|
||||
@line_items = order_permissions.
|
||||
editable_line_items.where(order_id: orders).
|
||||
includes(variant: { option_values: :option_type }).
|
||||
includes(:variant).
|
||||
ransack(params[:q]).result.
|
||||
reorder('spree_line_items.order_id ASC, spree_line_items.id ASC')
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ module Admin
|
||||
|
||||
after_action :geocode_address_if_use_geocoder, only: [:create, :update]
|
||||
|
||||
helper 'spree/products'
|
||||
include OrderCyclesHelper
|
||||
|
||||
def index
|
||||
@@ -187,7 +186,7 @@ module Admin
|
||||
if enterprises.present?
|
||||
enterprises.includes(
|
||||
supplied_products:
|
||||
[:supplier, { master: [:images], variants: { option_values: :option_type } }]
|
||||
[:supplier, :variants, { master: [:images] }]
|
||||
)
|
||||
end
|
||||
when :index
|
||||
|
||||
@@ -117,8 +117,7 @@ module Api
|
||||
def product_query_includes
|
||||
[
|
||||
master: { images: { attachment_attachment: :blob } },
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
|
||||
{ option_values: :option_type }]
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides]
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ module Api
|
||||
before_action :product
|
||||
|
||||
def index
|
||||
@variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
|
||||
@variants = scope.ransack(params[:q]).result
|
||||
render json: @variants, each_serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.includes(option_values: :option_type).find(params[:id])
|
||||
@variant = scope.find(params[:id])
|
||||
render json: @variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ require 'open_food_network/enterprise_injection_data'
|
||||
|
||||
class EnterprisesController < BaseController
|
||||
layout "darkswarm"
|
||||
helper Spree::ProductsHelper
|
||||
include OrderCyclesHelper
|
||||
include SerializerHelper
|
||||
include WhiteLabel
|
||||
|
||||
@@ -7,7 +7,6 @@ require 'open_food_network/permissions'
|
||||
module Spree
|
||||
module Admin
|
||||
class ProductsController < ::Admin::ResourceController
|
||||
helper 'spree/products'
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
include OrderCyclesHelper
|
||||
include EnterprisesHelper
|
||||
@@ -113,7 +112,6 @@ module Spree
|
||||
|
||||
def load_data
|
||||
@taxons = Taxon.order(:name)
|
||||
@option_types = OptionType.order(:name)
|
||||
@tax_categories = TaxCategory.order(:name)
|
||||
@shipping_categories = ShippingCategory.order(:name)
|
||||
end
|
||||
@@ -123,7 +121,7 @@ module Spree
|
||||
end
|
||||
|
||||
def product_includes
|
||||
[{ variants: [:images, { option_values: :option_type }] },
|
||||
[{ variants: [:images] },
|
||||
{ master: [:images, :default_price] }]
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ require 'open_food_network/scope_variants_for_search'
|
||||
module Spree
|
||||
module Admin
|
||||
class VariantsController < ::Admin::ResourceController
|
||||
helper 'spree/products'
|
||||
belongs_to 'spree/product', find_by: :permalink
|
||||
|
||||
before_action :assign_default_attributes, only: :new
|
||||
@@ -81,8 +80,6 @@ module Spree
|
||||
end
|
||||
|
||||
def create_before
|
||||
option_values = params[:new_variant]
|
||||
option_values&.each_value { |id| @object.option_values << OptionValue.find(id) }
|
||||
@object.save
|
||||
end
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module Spree
|
||||
layout 'darkswarm'
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :render_404
|
||||
helper 'spree/products', 'spree/orders'
|
||||
helper 'spree/orders'
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
module ProductsHelper
|
||||
def product_has_variant_unit_option_type?(product)
|
||||
product.option_types.any? { |option_type| variant_unit_option_type? option_type }
|
||||
end
|
||||
|
||||
def variant_unit_option_type?(option_type)
|
||||
Spree::Product.all_variant_unit_option_types.include? option_type
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -60,7 +60,7 @@ class ProducerMailer < ApplicationMailer
|
||||
|
||||
def line_items_from(order_cycle, producer)
|
||||
@line_items ||= Spree::LineItem.
|
||||
includes(:option_values, variant: [:product, { option_values: :option_type }]).
|
||||
includes(variant: [:product]).
|
||||
from_order_cycle(order_cycle).
|
||||
sorted_by_name_and_unit_value.
|
||||
merge(Spree::Product.with_deleted.in_supplier(producer)).
|
||||
|
||||
@@ -22,8 +22,6 @@ module Spree
|
||||
can :manage, :all
|
||||
else
|
||||
can [:index, :read], Country
|
||||
can [:index, :read], OptionType
|
||||
can [:index, :read], OptionValue
|
||||
can :create, Order
|
||||
can :read, Order do |order, token|
|
||||
order.user == user || order.token && token == order.token
|
||||
|
||||
@@ -9,7 +9,7 @@ module Spree
|
||||
include LineItemStockChanges
|
||||
|
||||
searchable_attributes :price, :quantity, :order_id, :variant_id, :tax_category_id
|
||||
searchable_associations :order, :order_cycle, :variant, :product, :supplier, :tax_category, :option_values
|
||||
searchable_associations :order, :order_cycle, :variant, :product, :supplier, :tax_category
|
||||
searchable_scopes :with_tax, :without_tax
|
||||
|
||||
belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items
|
||||
@@ -22,9 +22,6 @@ module Spree
|
||||
|
||||
has_many :adjustments, as: :adjustable, dependent: :destroy
|
||||
|
||||
has_and_belongs_to_many :option_values, join_table: 'spree_option_values_line_items',
|
||||
class_name: 'Spree::OptionValue'
|
||||
|
||||
before_validation :adjust_quantity
|
||||
before_validation :copy_price
|
||||
before_validation :copy_tax_category
|
||||
@@ -42,12 +39,16 @@ module Spree
|
||||
before_save :update_inventory
|
||||
before_save :calculate_final_weight_volume, if: :quantity_changed?,
|
||||
unless: :final_weight_volume_changed?
|
||||
after_save :update_order
|
||||
after_save :update_units
|
||||
before_destroy :update_inventory_before_destroy
|
||||
after_destroy :update_order
|
||||
before_save :assign_units, if: ->(line_item) {
|
||||
line_item.new_record? || line_item.final_weight_volume_changed?
|
||||
}
|
||||
|
||||
delegate :product, :unit_description, :display_name, to: :variant
|
||||
before_destroy :update_inventory_before_destroy
|
||||
|
||||
after_destroy :update_order
|
||||
after_save :update_order
|
||||
|
||||
delegate :product, :variant_unit, :unit_description, :display_name, :display_as, to: :variant
|
||||
|
||||
attr_accessor :skip_stock_check, :target_shipment # Allows manual skipping of Stock::AvailabilityValidator
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class OptionType < ApplicationRecord
|
||||
has_many :option_values, -> { order(:position) }, dependent: :destroy
|
||||
has_many :product_option_types, dependent: :destroy
|
||||
has_many :products, through: :product_option_types
|
||||
|
||||
validates :name, :presentation, presence: true
|
||||
default_scope -> { order("#{table_name}.position") }
|
||||
|
||||
accepts_nested_attributes_for :option_values,
|
||||
reject_if: lambda { |ov|
|
||||
ov[:name].blank? || ov[:presentation].blank?
|
||||
},
|
||||
allow_destroy: true
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class OptionValue < ApplicationRecord
|
||||
belongs_to :option_type
|
||||
acts_as_list scope: :option_type
|
||||
has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants',
|
||||
class_name: "Spree::Variant"
|
||||
|
||||
validates :name, :presentation, presence: true
|
||||
end
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class OptionValuesLineItem < ApplicationRecord
|
||||
belongs_to :line_item, class_name: 'Spree::LineItem'
|
||||
belongs_to :option_value, class_name: 'Spree::OptionValue'
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,6 @@ require 'concerns/product_stock'
|
||||
#
|
||||
# MASTER VARIANT
|
||||
# Every product has one master variant, which stores master price and sku, size and weight, etc.
|
||||
# The master variant does not have option values associated with it.
|
||||
# Price, SKU, size, weight, etc. are all delegated to the master variant.
|
||||
# Contains on_hand inventory levels only when there are no variants for the product.
|
||||
#
|
||||
@@ -33,11 +32,6 @@ module Spree
|
||||
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
|
||||
searchable_scopes :active, :with_properties
|
||||
|
||||
has_many :product_option_types, dependent: :destroy
|
||||
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
|
||||
# don't specify dependent => destroy on this association, it is not called. See:
|
||||
# https://github.com/rails/rails/issues/7618
|
||||
has_many :option_types, through: :product_option_types, dependent: :destroy
|
||||
has_many :product_properties, dependent: :destroy
|
||||
has_many :properties, through: :product_properties
|
||||
|
||||
@@ -87,7 +81,6 @@ module Spree
|
||||
delegate :images_attributes=, :display_as=, to: :master
|
||||
|
||||
after_create :set_master_variant_defaults
|
||||
after_create :build_variants_from_option_values_hash, if: :option_values_hash
|
||||
after_save :save_master
|
||||
|
||||
delegate :images, to: :master, prefix: true
|
||||
@@ -116,16 +109,12 @@ module Spree
|
||||
presence: { if: ->(p) { p.variant_unit == 'items' } }
|
||||
validate :validate_image_for_master
|
||||
|
||||
attr_accessor :option_values_hash
|
||||
|
||||
accepts_nested_attributes_for :product_properties,
|
||||
allow_destroy: true,
|
||||
reject_if: lambda { |pp| pp[:property_name].blank? }
|
||||
|
||||
make_permalink order: :name
|
||||
|
||||
alias :options :product_option_types
|
||||
|
||||
after_initialize :ensure_master
|
||||
after_initialize :set_available_on_to_now, if: :new_record?
|
||||
|
||||
@@ -260,32 +249,12 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures option_types and product_option_types exist for keys in option_values_hash
|
||||
def ensure_option_types_exist_for_values_hash
|
||||
return if option_values_hash.nil?
|
||||
|
||||
option_values_hash.keys.map(&:to_i).each do |id|
|
||||
option_type_ids << id unless option_type_ids.include?(id)
|
||||
unless product_option_types.pluck(:option_type_id).include?(id)
|
||||
product_option_types.create(option_type_id: id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# for adding products which are closely related to existing ones
|
||||
def duplicate
|
||||
duplicator = Spree::Core::ProductDuplicator.new(self)
|
||||
duplicator.duplicate
|
||||
end
|
||||
|
||||
# split variants list into hash which shows mapping of opt value onto matching variants
|
||||
# eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
|
||||
def categorise_variants_from_option(opt_type)
|
||||
return {} unless option_types.include?(opt_type)
|
||||
|
||||
variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } }
|
||||
end
|
||||
|
||||
def self.like_any(fields, values)
|
||||
where fields.map { |field|
|
||||
values.map { |value|
|
||||
@@ -351,21 +320,6 @@ module Spree
|
||||
variants.map(&:import_date).compact.max
|
||||
end
|
||||
|
||||
def variant_unit_option_type
|
||||
return if variant_unit.blank?
|
||||
|
||||
option_type_name = "unit_#{variant_unit}"
|
||||
option_type_presentation = variant_unit.capitalize
|
||||
|
||||
Spree::OptionType.find_by(name: option_type_name) ||
|
||||
Spree::OptionType.create!(name: option_type_name,
|
||||
presentation: option_type_presentation)
|
||||
end
|
||||
|
||||
def self.all_variant_unit_option_types
|
||||
Spree::OptionType.where('name LIKE ?', 'unit_%%')
|
||||
end
|
||||
|
||||
def destroy
|
||||
transaction do
|
||||
touch_distributors
|
||||
@@ -380,21 +334,6 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
# Builds variants from a hash of option types & values
|
||||
def build_variants_from_option_values_hash
|
||||
ensure_option_types_exist_for_values_hash
|
||||
values = option_values_hash.values
|
||||
values = values.inject(values.shift) { |memo, value| memo.product(value).map(&:flatten) }
|
||||
|
||||
values.each do |ids|
|
||||
variants.create(
|
||||
option_value_ids: ids,
|
||||
price: master.price
|
||||
)
|
||||
end
|
||||
save
|
||||
end
|
||||
|
||||
# ensures the master variant is flagged as such
|
||||
def set_master_variant_defaults
|
||||
master.is_master = true
|
||||
@@ -440,8 +379,6 @@ module Spree
|
||||
def update_units
|
||||
return unless saved_change_to_variant_unit? || saved_change_to_variant_unit_name?
|
||||
|
||||
option_types.delete self.class.all_variant_unit_option_types
|
||||
option_types << variant_unit_option_type if variant_unit.present?
|
||||
variants_including_master.each(&:update_units)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class ProductOptionType < ApplicationRecord
|
||||
after_destroy :remove_option_values
|
||||
|
||||
belongs_to :product, class_name: 'Spree::Product'
|
||||
belongs_to :option_type, class_name: 'Spree::OptionType'
|
||||
acts_as_list scope: :product
|
||||
|
||||
def remove_option_values
|
||||
product.variants_including_master.each do |variant|
|
||||
option_values = variant.option_values.where(option_type_id: option_type)
|
||||
variant.option_values.destroy(*option_values)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -14,9 +14,11 @@ module Spree
|
||||
acts_as_paranoid
|
||||
|
||||
searchable_attributes :sku, :display_as, :display_name
|
||||
searchable_associations :product, :option_values, :default_price
|
||||
searchable_associations :product, :default_price
|
||||
searchable_scopes :active, :deleted
|
||||
|
||||
NAME_FIELDS = ["display_name", "display_as", "weight", "unit_value", "unit_description"].freeze
|
||||
|
||||
belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product'
|
||||
|
||||
delegate_belongs_to :product, :name, :description, :permalink, :available_on,
|
||||
@@ -29,9 +31,6 @@ module Spree
|
||||
has_many :stock_items, dependent: :destroy, inverse_of: :variant
|
||||
has_many :stock_locations, through: :stock_items
|
||||
has_many :stock_movements
|
||||
|
||||
has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
|
||||
|
||||
has_many :images, -> { order(:position) }, as: :viewable,
|
||||
dependent: :destroy,
|
||||
class_name: "Spree::Image"
|
||||
@@ -73,14 +72,16 @@ module Spree
|
||||
before_validation :ensure_unit_value
|
||||
before_validation :update_weight_from_unit_value, if: ->(v) { v.product.present? }
|
||||
|
||||
before_save :convert_variant_weight_to_decimal
|
||||
before_save :assign_units, if: ->(variant) {
|
||||
variant.new_record? || variant.changed_attributes.keys.intersection(NAME_FIELDS).any?
|
||||
}
|
||||
|
||||
after_save :save_default_price
|
||||
after_save :update_units
|
||||
|
||||
after_create :create_stock_items
|
||||
after_create :set_position
|
||||
|
||||
before_save :convert_variant_weight_to_decimal
|
||||
|
||||
around_destroy :destruction
|
||||
|
||||
# default variant scope only lists non-deleted variants
|
||||
@@ -177,10 +178,6 @@ module Spree
|
||||
order_cycle).fees_name_by_type_for self
|
||||
end
|
||||
|
||||
def option_value(opt_name)
|
||||
option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
|
||||
end
|
||||
|
||||
def price_in(currency)
|
||||
prices.select{ |price| price.currency == currency }.first ||
|
||||
Spree::Price.new(variant_id: id, currency: currency)
|
||||
|
||||
@@ -4,18 +4,18 @@ require "open_food_network/i18n_inflections"
|
||||
|
||||
module VariantUnits
|
||||
class OptionValueNamer
|
||||
def initialize(variant = nil)
|
||||
@variant = variant
|
||||
# nameable can be either a Spree::LineItem or a Spree::Variant
|
||||
def initialize(nameable = nil)
|
||||
@nameable = nameable
|
||||
end
|
||||
|
||||
def name(obj = nil)
|
||||
@variant = obj unless obj.nil?
|
||||
def name
|
||||
value, unit = option_value_value_unit
|
||||
separator = value_scaled? ? '' : ' '
|
||||
|
||||
name_fields = []
|
||||
name_fields << "#{value}#{separator}#{unit}" if value.present? && unit.present?
|
||||
name_fields << @variant.unit_description if @variant.unit_description.present?
|
||||
name_fields << @nameable.unit_description if @nameable.unit_description.present?
|
||||
name_fields.join ' '
|
||||
end
|
||||
|
||||
@@ -32,16 +32,16 @@ module VariantUnits
|
||||
private
|
||||
|
||||
def value_scaled?
|
||||
@variant.product.variant_unit_scale.present?
|
||||
@nameable.product.variant_unit_scale.present?
|
||||
end
|
||||
|
||||
def option_value_value_unit
|
||||
if @variant.unit_value.present?
|
||||
if %w(weight volume).include? @variant.product.variant_unit
|
||||
if @nameable.unit_value.present? && @nameable.product&.persisted?
|
||||
if %w(weight volume).include? @nameable.product.variant_unit
|
||||
value, unit_name = option_value_value_unit_scaled
|
||||
else
|
||||
value = @variant.unit_value
|
||||
unit_name = pluralize(@variant.product.variant_unit_name, value)
|
||||
value = @nameable.unit_value
|
||||
unit_name = pluralize(@nameable.product.variant_unit_name, value)
|
||||
end
|
||||
|
||||
value = value.to_i if value == value.to_i
|
||||
@@ -56,13 +56,13 @@ module VariantUnits
|
||||
def option_value_value_unit_scaled
|
||||
unit_scale, unit_name = scale_for_unit_value
|
||||
|
||||
value = (@variant.unit_value / unit_scale).to_d.truncate(2)
|
||||
value = (@nameable.unit_value / unit_scale).to_d.truncate(2)
|
||||
|
||||
[value, unit_name]
|
||||
end
|
||||
|
||||
def scale_for_unit_value
|
||||
WeightsAndMeasures.new(@variant).scale_for_unit_value
|
||||
WeightsAndMeasures.new(@nameable).scale_for_unit_value
|
||||
end
|
||||
|
||||
def pluralize(unit_name, count)
|
||||
|
||||
@@ -8,31 +8,12 @@ require 'variant_units/option_value_namer'
|
||||
|
||||
module VariantUnits
|
||||
module VariantAndLineItemNaming
|
||||
# Copied and modified from Spree::Variant
|
||||
def options_text
|
||||
values = if option_values_eager_loaded?
|
||||
# Don't trigger N+1 queries if option_values are already eager-loaded.
|
||||
# For best results, use: `Spree::Variant.includes(option_values: :option_type)`
|
||||
# or: `Spree::Product.includes(variant: {option_values: :option_type})`
|
||||
option_values.sort_by{ |o| o.option_type.position }
|
||||
else
|
||||
option_values.joins(:option_type).
|
||||
order("#{Spree::OptionType.table_name}.position asc")
|
||||
end
|
||||
|
||||
values.map { |option_value|
|
||||
presentation(option_value)
|
||||
}.to_sentence(words_connector: ", ", two_words_connector: ", ")
|
||||
end
|
||||
|
||||
def presentation(option_value)
|
||||
return option_value.presentation unless option_value.option_type.name == "unit_weight"
|
||||
|
||||
return unit_presentation unless variant_unit == "weight"
|
||||
return display_as if has_attribute?(:display_as) && display_as.present?
|
||||
|
||||
return variant.display_as if variant_display_as?
|
||||
|
||||
option_value.presentation
|
||||
unit_presentation
|
||||
end
|
||||
|
||||
def variant_display_as?
|
||||
@@ -68,28 +49,23 @@ module VariantUnits
|
||||
|
||||
def unit_to_display
|
||||
return display_as if has_attribute?(:display_as) && display_as.present?
|
||||
|
||||
return variant.display_as if variant_display_as?
|
||||
|
||||
options_text
|
||||
end
|
||||
|
||||
def update_units
|
||||
delete_unit_option_values
|
||||
|
||||
option_type = product.variant_unit_option_type
|
||||
if option_type
|
||||
name = option_value_name
|
||||
ov = Spree::OptionValue.where(option_type_id: option_type, name: name,
|
||||
presentation: name).first ||
|
||||
Spree::OptionValue.create!(option_type: option_type, name: name, presentation: name)
|
||||
option_values << ov
|
||||
end
|
||||
def assign_units
|
||||
assign_attributes(unit_value_attributes)
|
||||
end
|
||||
|
||||
def delete_unit_option_values
|
||||
ovs = option_values.where(option_type_id: Spree::Product.all_variant_unit_option_types)
|
||||
option_values.destroy ovs
|
||||
def update_units
|
||||
update_columns(unit_value_attributes)
|
||||
end
|
||||
|
||||
def unit_value_attributes
|
||||
units = { unit_presentation: option_value_name }
|
||||
units.merge!(variant_unit: product.variant_unit) if has_attribute?(:variant_unit)
|
||||
units
|
||||
end
|
||||
|
||||
def weight_from_unit_value
|
||||
@@ -98,17 +74,10 @@ module VariantUnits
|
||||
|
||||
private
|
||||
|
||||
def option_values_eager_loaded?
|
||||
option_values.loaded?
|
||||
end
|
||||
|
||||
def option_value_name
|
||||
if has_attribute?(:display_as) && display_as.present?
|
||||
display_as
|
||||
else
|
||||
option_value_namer = VariantUnits::OptionValueNamer.new self
|
||||
option_value_namer.name
|
||||
end
|
||||
return display_as if has_attribute?(:display_as) && display_as.present?
|
||||
|
||||
VariantUnits::OptionValueNamer.new(self).name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
%tr{id: "#{spree_dom_id(f.object)}", class: "#{cycle('odd', 'even')}"}
|
||||
%td
|
||||
= f.object.variant.product.name
|
||||
= "(#{f.object.full_name})" unless f.object.variant.option_values.empty?
|
||||
= "(#{f.object.full_name})"
|
||||
%td.price.align-center
|
||||
= f.object.single_display_amount
|
||||
%td.qty
|
||||
|
||||
@@ -6,28 +6,18 @@
|
||||
= f.label :display_as, t('.display_as')
|
||||
= f.text_field :display_as, class: "fullwidth", placeholder: t('.display_as_placeholder')
|
||||
|
||||
- if product_has_variant_unit_option_type?(@product)
|
||||
- if @product.variant_unit != 'items'
|
||||
.field
|
||||
= label_tag :unit_value_human, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})"
|
||||
= hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale
|
||||
= number_field_tag :unit_value_human, nil, {class: "fullwidth", step: 0.01, 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'}
|
||||
= f.number_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'}
|
||||
|
||||
- if @product.variant_unit != 'items'
|
||||
.field
|
||||
= f.label :unit_description, t(:spree_admin_unit_description)
|
||||
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
|
||||
= label_tag :unit_value_human, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})"
|
||||
= hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale
|
||||
= number_field_tag :unit_value_human, nil, {class: "fullwidth", step: 0.01, 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'}
|
||||
= f.number_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'}
|
||||
|
||||
.field
|
||||
= f.label :unit_description, t(:spree_admin_unit_description)
|
||||
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
|
||||
|
||||
%div
|
||||
- @product.option_types.each do |option_type|
|
||||
- unless variant_unit_option_type?(option_type)
|
||||
.field
|
||||
= label :new_variant, option_type.presentation
|
||||
- if @variant.new_record?
|
||||
= select(:new_variant, option_type.presentation, option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] }, {}, {class: 'select2 fullwidth'})
|
||||
- else
|
||||
- if opt = @variant.option_values.detect {|o| o.option_type == option_type }.try(:presentation)
|
||||
= text_field(:new_variant, option_type.presentation, value: opt, disabled: 'disabled', class: 'fullwidth')
|
||||
.field
|
||||
= f.label :sku, t('.sku')
|
||||
= f.text_field :sku, class: 'fullwidth'
|
||||
|
||||
74
db/migrate/20230505165821_variant_options_columns.rb
Normal file
74
db/migrate/20230505165821_variant_options_columns.rb
Normal file
@@ -0,0 +1,74 @@
|
||||
class VariantOptionsColumns < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
add_column :spree_variants, :variant_unit, :string
|
||||
add_column :spree_variants, :unit_presentation, :string
|
||||
add_column :spree_line_items, :unit_presentation, :string
|
||||
|
||||
migrate_variant_unit
|
||||
migrate_variant_presentation
|
||||
migrate_line_item_presentation
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :spree_variants, :variant_unit
|
||||
remove_column :spree_variants, :unit_presentation
|
||||
remove_column :spree_line_items, :unit_presentation
|
||||
end
|
||||
|
||||
# Migrates variant's product's variant_unit value onto variant
|
||||
#
|
||||
# Spree::Variant.includes(:product).each do |variant|
|
||||
# variant.update_columns(variant_unit: variant.product.variant_unit)
|
||||
# end
|
||||
def migrate_variant_unit
|
||||
ActiveRecord::Base.connection.execute(<<-SQL
|
||||
UPDATE spree_variants
|
||||
SET variant_unit = product.variant_unit
|
||||
FROM spree_products AS product
|
||||
WHERE spree_variants.product_id = product.id
|
||||
SQL
|
||||
)
|
||||
end
|
||||
|
||||
# Migrates the variants' option_value's presentation onto the variant's unit_presentation
|
||||
#
|
||||
# Spree::Variant.includes(:option_values: :option_type).each do |variant|
|
||||
# variant.update_columns(unit_presentation: variant.option_values.first.presentation)
|
||||
# end
|
||||
def migrate_variant_presentation
|
||||
ActiveRecord::Base.connection.execute(<<-SQL
|
||||
UPDATE spree_variants
|
||||
SET unit_presentation = option_values.presentation
|
||||
FROM (
|
||||
SELECT
|
||||
DISTINCT ON (spree_option_values_variants.variant_id) variant_id,
|
||||
spree_option_values.presentation AS presentation
|
||||
FROM spree_option_values_variants
|
||||
LEFT JOIN spree_option_values ON spree_option_values.id = spree_option_values_variants.option_value_id
|
||||
) option_values
|
||||
WHERE spree_variants.id = option_values.variant_id
|
||||
SQL
|
||||
)
|
||||
end
|
||||
|
||||
# Migrates the line_items' option_value's presentation onto the line_items's unit_presentation
|
||||
#
|
||||
# Spree::LineItem.includes(:option_values: :option_type).each do |line_item|
|
||||
# line_item.update_columns(unit_presentation: line_item.option_values.first.presentation)
|
||||
# end
|
||||
def migrate_line_item_presentation
|
||||
ActiveRecord::Base.connection.execute(<<-SQL
|
||||
UPDATE spree_line_items
|
||||
SET unit_presentation = option_values.presentation
|
||||
FROM (
|
||||
SELECT
|
||||
DISTINCT ON (spree_option_values_line_items.line_item_id) line_item_id,
|
||||
spree_option_values.presentation AS presentation
|
||||
FROM spree_option_values_line_items
|
||||
LEFT JOIN spree_option_values ON spree_option_values.id = spree_option_values_line_items.option_value_id
|
||||
) option_values
|
||||
WHERE spree_line_items.id = option_values.line_item_id
|
||||
SQL
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -549,6 +549,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_22_120633) do
|
||||
t.decimal "height", precision: 8, scale: 2
|
||||
t.decimal "width", precision: 8, scale: 2
|
||||
t.decimal "depth", precision: 8, scale: 2
|
||||
t.string "unit_presentation"
|
||||
t.index ["order_id"], name: "index_line_items_on_order_id"
|
||||
t.index ["variant_id"], name: "index_line_items_on_variant_id"
|
||||
end
|
||||
@@ -1076,6 +1077,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_22_120633) do
|
||||
t.string "display_name", limit: 255
|
||||
t.string "display_as", limit: 255
|
||||
t.datetime "import_date", precision: nil
|
||||
t.string "variant_unit"
|
||||
t.string "unit_presentation"
|
||||
t.index ["product_id"], name: "index_variants_on_product_id"
|
||||
t.index ["sku"], name: "index_spree_variants_on_sku"
|
||||
t.check_constraint "unit_value > 0::double precision", name: "positive_unit_value"
|
||||
|
||||
@@ -12,14 +12,14 @@ module OrderManagement
|
||||
let!(:product2) { create(:product, supplier: shop) }
|
||||
let!(:product3) { create(:product, supplier: shop) }
|
||||
let!(:variant1) {
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00)
|
||||
}
|
||||
let!(:variant2) {
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00)
|
||||
}
|
||||
let!(:variant3) {
|
||||
create(:variant, product: product2, unit_value: '1000',
|
||||
price: 2.50, option_values: [], on_hand: 1)
|
||||
price: 2.50, on_hand: 1)
|
||||
}
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle1) {
|
||||
|
||||
@@ -34,7 +34,6 @@ module OpenFoodNetwork
|
||||
|
||||
def query_scope
|
||||
Spree::Variant.where(is_master: false).
|
||||
includes(option_values: :option_type).
|
||||
ransack(search_params.merge(m: 'or')).
|
||||
result.
|
||||
order("spree_products.name, display_name, display_as, spree_products.variant_unit_name").
|
||||
|
||||
@@ -40,13 +40,6 @@ module Reporting
|
||||
def joins_order_bill_address
|
||||
reflect query.join(association(Spree::Order, :bill_address, bill_address_alias))
|
||||
end
|
||||
|
||||
def join_line_item_option_values
|
||||
reflect query.
|
||||
join(association(Spree::LineItem, :option_values)).
|
||||
join(association(Spree::OptionValuesLineItem, :option_value)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,7 +65,7 @@ module Reporting
|
||||
def variant_full_name
|
||||
display_name = variant_table[:display_name]
|
||||
display_as = variant_table[:display_as]
|
||||
options_text = option_value_table[:presentation]
|
||||
options_text = variant_table[:unit_presentation]
|
||||
|
||||
unit_to_display = coalesce(nullify_empty_strings(display_as), options_text)
|
||||
combined_description = sql_concat(display_name, raw("' ('"), unit_to_display, raw("')'"))
|
||||
|
||||
@@ -39,10 +39,6 @@ module Reporting
|
||||
Spree::Order.arel_table.alias(:managed_orders)
|
||||
end
|
||||
|
||||
def option_value_table
|
||||
Spree::OptionValue.arel_table
|
||||
end
|
||||
|
||||
def shipping_category_table
|
||||
Spree::ShippingCategory.arel_table
|
||||
end
|
||||
|
||||
@@ -22,9 +22,8 @@ module Reporting
|
||||
[
|
||||
{
|
||||
order: [:bill_address],
|
||||
variant: [{ option_values: :option_type }, { product: :supplier }]
|
||||
},
|
||||
:option_values
|
||||
variant: { product: :supplier }
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ module Reporting
|
||||
end
|
||||
|
||||
def line_item_includes
|
||||
[{ variant: [{ option_values: :option_type }, { product: :supplier }],
|
||||
[{ variant: { product: :supplier },
|
||||
order: [:bill_address, :ship_address, :order_cycle, :adjustments, :payments,
|
||||
:user, :distributor, :shipments] }]
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ module Reporting
|
||||
:adjustments,
|
||||
{ shipments: { shipping_rates: :shipping_method } }
|
||||
],
|
||||
variant: [{ option_values: :option_type }, { product: :supplier }]
|
||||
variant: { product: :supplier }
|
||||
}]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ module Reporting
|
||||
end
|
||||
|
||||
def line_item_includes
|
||||
[{ variant: [{ option_values: :option_type }, { product: :supplier }] }]
|
||||
[{ variant: { product: :supplier } }]
|
||||
end
|
||||
|
||||
def query_result
|
||||
|
||||
@@ -41,7 +41,7 @@ module Reporting
|
||||
|
||||
def line_item_includes
|
||||
[{ order: :distributor,
|
||||
variant: [{ option_values: :option_type }, { product: :supplier }] }]
|
||||
variant: { product: :supplier } }]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,7 +20,6 @@ module Reporting
|
||||
joins_variant_product.
|
||||
joins_product_supplier.
|
||||
joins_product_shipping_category.
|
||||
join_line_item_option_values.
|
||||
selecting(select_fields).
|
||||
ordered_by(ordering_fields)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,6 @@ module Reporting
|
||||
def child_variants
|
||||
Spree::Variant.
|
||||
where(is_master: false).
|
||||
includes(option_values: :option_type).
|
||||
joins(:product).
|
||||
merge(visible_products).
|
||||
order('spree_products.name')
|
||||
|
||||
@@ -62,7 +62,7 @@ module Reporting
|
||||
|
||||
def line_item_includes
|
||||
[:bill_address, :adjustments,
|
||||
{ line_items: { variant: [{ option_values: :option_type }, { product: :supplier }] } }]
|
||||
{ line_items: { variant: { product: :supplier } } }]
|
||||
end
|
||||
|
||||
def detail_rows_for_order(order, invoice_number, opts)
|
||||
|
||||
@@ -11,8 +11,6 @@ module Spree
|
||||
|
||||
def duplicate
|
||||
new_product = duplicate_product
|
||||
new_product.option_types = product.option_types
|
||||
|
||||
new_product.save!
|
||||
new_product
|
||||
end
|
||||
|
||||
@@ -27,11 +27,9 @@ class RemoveTransientData
|
||||
merge(orders_without_payments)
|
||||
|
||||
old_cart_line_items = Spree::LineItem.where(order_id: old_carts)
|
||||
old_line_item_options = Spree::OptionValuesLineItem.where(line_item_id: old_cart_line_items)
|
||||
old_cart_adjustments = Spree::Adjustment.where(order_id: old_carts)
|
||||
|
||||
old_cart_adjustments.delete_all
|
||||
old_line_item_options.delete_all
|
||||
old_cart_line_items.delete_all
|
||||
old_carts.delete_all
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ describe Admin::SubscriptionLineItemsController, type: :controller do
|
||||
let(:unmanaged_shop) { create(:enterprise) }
|
||||
let!(:product) { create(:product) }
|
||||
let!(:variant) {
|
||||
create(:variant, product: product, unit_value: '100', price: 15.00, option_values: [])
|
||||
create(:variant, product: product, unit_value: '100', price: 15.00)
|
||||
}
|
||||
let!(:outgoing_exchange) {
|
||||
order_cycle.exchanges.create(sender: shop, receiver: shop, variants: [variant],
|
||||
|
||||
@@ -262,7 +262,7 @@ describe Admin::SubscriptionsController, type: :controller do
|
||||
let!(:customer) { create(:customer, enterprise: shop) }
|
||||
let!(:product1) { create(:product, supplier: shop) }
|
||||
let!(:variant1) {
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00)
|
||||
}
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle) {
|
||||
@@ -373,7 +373,7 @@ describe Admin::SubscriptionsController, type: :controller do
|
||||
context 'with subscription_line_items params' do
|
||||
let!(:product2) { create(:product) }
|
||||
let!(:variant2) {
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00)
|
||||
}
|
||||
|
||||
before do
|
||||
|
||||
@@ -61,7 +61,7 @@ describe Api::V0::ProductsController, type: :controller do
|
||||
api_get :show, id: product.to_param
|
||||
|
||||
expect(json_response["permalink_live"]).to match(/and-1-ways/)
|
||||
product.destroy
|
||||
product.reload.destroy
|
||||
|
||||
api_get :show, id: other_product.id
|
||||
expect(json_response["permalink_live"]).to match(/droids/)
|
||||
|
||||
@@ -24,7 +24,6 @@ describe Api::V0::VariantsController, type: :controller do
|
||||
let!(:product) { create(:product) }
|
||||
let!(:variant) do
|
||||
variant = product.master
|
||||
variant.option_values << create(:option_value)
|
||||
variant
|
||||
end
|
||||
|
||||
@@ -46,17 +45,18 @@ describe Api::V0::VariantsController, type: :controller do
|
||||
# Regression test for spree#2141
|
||||
context "a deleted variant" do
|
||||
before do
|
||||
expect(Spree::Variant.count).to eq 11
|
||||
variant.update_column(:deleted_at, Time.zone.now)
|
||||
end
|
||||
|
||||
it "is not returned in the results" do
|
||||
api_get :index
|
||||
expect(json_response.count).to eq(10) # there are 11 variants
|
||||
expect(json_response.count).to eq(10)
|
||||
end
|
||||
|
||||
it "is not returned even when show_deleted is passed" do
|
||||
api_get :index, show_deleted: true
|
||||
expect(json_response.count).to eq(10) # there are 11 variants
|
||||
expect(json_response.count).to eq(10)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :option_value, class: Spree::OptionValue do
|
||||
name { 'Size' }
|
||||
presentation { 'S' }
|
||||
option_type
|
||||
end
|
||||
|
||||
factory :option_type, class: Spree::OptionType do
|
||||
name { 'foo-size' }
|
||||
presentation { 'Size' }
|
||||
|
||||
# Prevent inconsistent ordering in specs when all option types have the same (0) position
|
||||
sequence(:position)
|
||||
end
|
||||
end
|
||||
@@ -34,10 +34,7 @@ FactoryBot.define do
|
||||
after(:create) do |product, evaluator|
|
||||
product.master.on_hand = evaluator.on_hand
|
||||
product.variants.first.on_hand = evaluator.on_hand
|
||||
end
|
||||
|
||||
factory :product_with_option_types do
|
||||
after(:create) { |product| create(:product_option_type, product: product) }
|
||||
product.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -60,6 +57,7 @@ FactoryBot.define do
|
||||
product.master.on_hand = evaluator.on_hand
|
||||
product.variants.first.on_demand = evaluator.on_demand
|
||||
product.variants.first.on_hand = evaluator.on_hand
|
||||
product.reload
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :product_option_type, class: Spree::ProductOptionType do
|
||||
product
|
||||
option_type
|
||||
end
|
||||
end
|
||||
@@ -12,7 +12,6 @@ FactoryBot.define do
|
||||
depth { generate(:random_float) }
|
||||
|
||||
product { |p| p.association(:base_product) }
|
||||
option_values { [create(:option_value)] }
|
||||
|
||||
# ensure stock item will be created for this variant
|
||||
before(:create) { create(:stock_location) if Spree::StockLocation.count.zero? }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Hub,Customer,Email,Phone,Producer,Product,Variant,Quantity,Item ($),Item + Fees ($),Admin & Handling ($),Ship ($),Pay fee ($),Total ($),Paid?,Shipping,Delivery?,Ship Street,Ship Street 2,Ship City,Ship Postcode,Ship State,Comments,SKU,Order Cycle,Payment Method,Customer Code,Tags,Billing Street,Billing Street 2,Billing City,Billing Postcode,Billing State,Order number,Date
|
||||
Apple Market,John Doe,john@example.net,123-456-7890,Apple Farmer,Apples,"1g, S",1,10.0,10.0,"","","","",false,UPS Ground,true,10 Lovely Street,Northwest,Herndon,20170,Victoria,"",APP,,,JHN,"",10 Lovely Street,Northwest,Herndon,20170,Victoria,R644360121,2022-05-26 00:00:00
|
||||
Apple Market,John Doe,john@example.net,123-456-7890,Apple Farmer,Apples,1g,1,10.0,10.0,"","","","",false,UPS Ground,true,10 Lovely Street,Northwest,Herndon,20170,Victoria,"",APP,,,JHN,"",10 Lovely Street,Northwest,Herndon,20170,Victoria,R644360121,2022-05-26 00:00:00
|
||||
|
||||
|
@@ -9,8 +9,7 @@ describe Spree::Core::ProductDuplicator do
|
||||
taxons: [],
|
||||
product_properties: [property],
|
||||
master: master_variant,
|
||||
variants: [variant],
|
||||
option_types: []
|
||||
variants: [variant]
|
||||
end
|
||||
|
||||
let(:new_product) do
|
||||
@@ -89,7 +88,6 @@ describe Spree::Core::ProductDuplicator do
|
||||
expect(new_product).to receive(:updated_at=).with(nil)
|
||||
expect(new_product).to receive(:deleted_at=).with(nil)
|
||||
expect(new_product).to receive(:master=).with(new_master_variant)
|
||||
expect(new_product).to receive(:option_types=).with([])
|
||||
expect(new_product).to receive(:variants=).with([new_variant])
|
||||
|
||||
expect(new_master_variant).to receive(:sku=).with("")
|
||||
|
||||
@@ -63,13 +63,6 @@ describe RemoveTransientData do
|
||||
expect{ old_line_item.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
expect{ old_adjustment.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "removes any defunct line item option value records" do
|
||||
line_item.delete
|
||||
|
||||
expect{ RemoveTransientData.new.call }.
|
||||
to change{ Spree::OptionValuesLineItem.count }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -71,20 +71,6 @@ describe Spree::Ability do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for OptionType' do
|
||||
let(:resource) { Spree::OptionType.new }
|
||||
context 'requested by any user' do
|
||||
it_should_behave_like 'read only'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for OptionValue' do
|
||||
let(:resource) { Spree::OptionType.new }
|
||||
context 'requested by any user' do
|
||||
it_should_behave_like 'read only'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for Order' do
|
||||
let(:resource) { Spree::Order.new }
|
||||
|
||||
|
||||
@@ -178,12 +178,12 @@ module Spree
|
||||
|
||||
before do
|
||||
li1
|
||||
li2
|
||||
li2.reload
|
||||
li1.adjustments << adjustment1
|
||||
end
|
||||
|
||||
it "finds line items with tax" do
|
||||
expect(LineItem.with_tax).to eq([li1])
|
||||
expect(LineItem.with_tax.to_a).to eq([li1])
|
||||
end
|
||||
|
||||
it "finds line items without tax" do
|
||||
@@ -708,47 +708,41 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
context "when the line_item already has a final_weight_volume set (and all required option values do not exist)" do
|
||||
context "when the line_item has a final_weight_volume set" do
|
||||
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:v) { create(:variant, product: p0, unit_value: 10, unit_description: 'bar') }
|
||||
|
||||
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:li) { create(:line_item, product: p, final_weight_volume: 5) }
|
||||
|
||||
it "removes the old option value and assigns the new one" do
|
||||
ov_orig = li.option_values.last
|
||||
ov_var = v.option_values.last
|
||||
it "assigns the new value" do
|
||||
expect(li.unit_presentation).to eq "5g"
|
||||
expect(v.unit_presentation).to eq "10g bar"
|
||||
|
||||
allow(li).to receive(:unit_description) { 'foo' }
|
||||
|
||||
expect {
|
||||
li.update_attribute(:final_weight_volume, 10)
|
||||
}.to change(Spree::OptionValue, :count).by(1)
|
||||
li.update_attribute(:final_weight_volume, 10)
|
||||
|
||||
expect(li.option_values).not_to include ov_orig
|
||||
expect(li.option_values).not_to include ov_var
|
||||
ov = li.option_values.last
|
||||
expect(ov.name).to eq("10g foo")
|
||||
expect(li.unit_presentation).to eq "10g foo"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the variant already has a value set (and all required option values exist)" do
|
||||
context "when the variant already has a value set" do
|
||||
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:v) { create(:variant, product: p0, unit_value: 10, unit_description: 'bar') }
|
||||
|
||||
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:li) { create(:line_item, product: p, final_weight_volume: 5) }
|
||||
|
||||
it "removes the old option value and assigns the new one" do
|
||||
ov_orig = li.option_values.last
|
||||
ov_new = v.option_values.last
|
||||
it "assigns the new value" do
|
||||
expect(li.unit_presentation).to eq "5g"
|
||||
expect(v.unit_presentation).to eq "10g bar"
|
||||
|
||||
allow(li).to receive(:unit_description) { 'bar' }
|
||||
|
||||
expect {
|
||||
li.update_attribute(:final_weight_volume, 10)
|
||||
}.to change(Spree::OptionValue, :count).by(0)
|
||||
li.update_attribute(:final_weight_volume, 10)
|
||||
|
||||
expect(li.option_values).not_to include ov_orig
|
||||
expect(li.option_values).to include ov_new
|
||||
expect(li.unit_presentation).to eq "10g bar"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -792,24 +786,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
describe "deleting unit option values" do
|
||||
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:ot) { Spree::OptionType.find_by name: 'unit_weight' }
|
||||
let!(:li) { create(:line_item, product: p) }
|
||||
|
||||
it "removes option value associations for unit option types" do
|
||||
expect {
|
||||
li.delete_unit_option_values
|
||||
}.to change(li.option_values, :count).by(-1)
|
||||
end
|
||||
|
||||
it "does not delete option values" do
|
||||
expect {
|
||||
li.delete_unit_option_values
|
||||
}.to change(Spree::OptionValue, :count).by(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the associated variant is soft-deleted" do
|
||||
let!(:variant) { create(:variant) }
|
||||
let!(:line_item) { create(:line_item, variant: variant) }
|
||||
|
||||
@@ -881,7 +881,7 @@ module Spree
|
||||
end
|
||||
|
||||
describe "variant units" do
|
||||
context "when the product already has a variant unit set (and all required option types exist)" do
|
||||
context "when the product already has a variant unit set" do
|
||||
let!(:p) {
|
||||
create(:simple_product,
|
||||
variant_unit: 'weight',
|
||||
@@ -889,84 +889,27 @@ module Spree
|
||||
variant_unit_name: nil)
|
||||
}
|
||||
|
||||
let!(:ot_volume) { create(:option_type, name: 'unit_volume', presentation: 'Volume') }
|
||||
|
||||
it "removes the old option type and assigns the new one" do
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
expect(p.option_types).to eq([ot_volume])
|
||||
end
|
||||
|
||||
it "does not remove and re-add the option type if it is not changed" do
|
||||
expect(p.option_types).to receive(:delete).never
|
||||
p.update!(name: 'foo')
|
||||
end
|
||||
|
||||
it "removes the related option values from all its variants and replaces them" do
|
||||
ot = Spree::OptionType.find_by name: 'unit_weight'
|
||||
it "updates its variants unit values" do
|
||||
v = create(:variant, unit_value: 1, product: p)
|
||||
p.reload
|
||||
|
||||
expect(v.option_values.map(&:name).include?("1L")).to eq(false)
|
||||
expect(v.option_values.map(&:name).include?("1g")).to eq(true)
|
||||
expect {
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
}.to change(p.master.option_values.reload, :count).by(0)
|
||||
v.reload
|
||||
expect(v.option_values.map(&:name).include?("1L")).to eq(true)
|
||||
expect(v.option_values.map(&:name).include?("1g")).to eq(false)
|
||||
expect(v.unit_presentation).to eq "1g"
|
||||
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
|
||||
expect(v.reload.unit_presentation).to eq "1L"
|
||||
end
|
||||
|
||||
it "removes the related option values from its master variant and replaces them" do
|
||||
ot = Spree::OptionType.find_by name: 'unit_weight'
|
||||
it "updates its master variant's unit values" do
|
||||
p.master.update!(unit_value: 1)
|
||||
p.reload
|
||||
|
||||
expect(p.master.option_values.map(&:name).include?("1L")).to eq(false)
|
||||
expect(p.master.option_values.map(&:name).include?("1g")).to eq(true)
|
||||
expect {
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
}.to change(p.master.option_values.reload, :count).by(0)
|
||||
expect(p.master.unit_presentation).to eq "1g"
|
||||
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
p.reload
|
||||
expect(p.master.option_values.map(&:name).include?("1L")).to eq(true)
|
||||
expect(p.master.option_values.map(&:name).include?("1g")).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
it "finds all variant unit option types" do
|
||||
ot1 = create(:option_type, name: 'unit_weight', presentation: 'Weight')
|
||||
ot2 = create(:option_type, name: 'unit_volume', presentation: 'Volume')
|
||||
ot3 = create(:option_type, name: 'unit_items', presentation: 'Items')
|
||||
ot4 = create(:option_type, name: 'foo_unit_bar', presentation: 'Foo')
|
||||
|
||||
expect(Spree::Product.all_variant_unit_option_types).to match_array [ot1, ot2, ot3]
|
||||
end
|
||||
end
|
||||
|
||||
describe "option types" do
|
||||
describe "removing an option type" do
|
||||
it "removes the associated option values from all variants" do
|
||||
# Given a product with a variant unit option type and values
|
||||
p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1)
|
||||
v1 = create(:variant, product: p, unit_value: 100, option_values: [])
|
||||
v2 = create(:variant, product: p, unit_value: 200, option_values: [])
|
||||
|
||||
# And a custom option type and values
|
||||
ot = create(:option_type, name: 'foo', presentation: 'foo')
|
||||
p.option_types << ot
|
||||
ov1 = create(:option_value, option_type: ot, name: 'One', presentation: 'One')
|
||||
ov2 = create(:option_value, option_type: ot, name: 'Two', presentation: 'Two')
|
||||
v1.option_values << ov1
|
||||
v2.option_values << ov2
|
||||
|
||||
# When we remove the custom option type
|
||||
p.option_type_ids = p.option_type_ids.reject { |id| id == ot.id }
|
||||
|
||||
# Then the associated option values should have been removed from the variants
|
||||
expect(v1.option_values.reload).not_to include ov1
|
||||
expect(v2.option_values.reload).not_to include ov2
|
||||
|
||||
# And the option values themselves should still exist
|
||||
expect(Spree::OptionValue.where(id: [ov1.id, ov2.id]).count).to eq(2)
|
||||
expect(p.master.unit_presentation).to eq "1L"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ describe Spree::Shipment do
|
||||
|
||||
context "manifest" do
|
||||
let(:order) { Spree::Order.create }
|
||||
let(:variant) { create(:variant) }
|
||||
let!(:variant) { create(:variant) }
|
||||
let!(:line_item) { order.contents.add variant }
|
||||
let!(:shipment) { order.create_proposed_shipments.first }
|
||||
|
||||
|
||||
@@ -567,8 +567,7 @@ describe Spree::Variant do
|
||||
end
|
||||
|
||||
describe "unit value/description" do
|
||||
let(:v) { Spree::Variant.new(option_values: [option_value]) }
|
||||
let(:option_value) { build(:option_value, presentation: "small") }
|
||||
let(:v) { Spree::Variant.new(unit_presentation: "small" ) }
|
||||
|
||||
describe "generating the full name" do
|
||||
it "returns unit_to_display when display_name is blank" do
|
||||
@@ -583,7 +582,7 @@ describe Spree::Variant do
|
||||
|
||||
it "returns unit_to_display when it contains display_name" do
|
||||
v.display_name = "small"
|
||||
v.option_values[0].presentation = "small size"
|
||||
v.unit_presentation = "small size"
|
||||
expect(v.full_name).to eq "small size"
|
||||
end
|
||||
|
||||
@@ -594,7 +593,7 @@ describe Spree::Variant do
|
||||
|
||||
it "is resilient to regex chars" do
|
||||
v.display_name = ")))"
|
||||
v.option_values[0].presentation = ")))"
|
||||
v.unit_presentation = ")))"
|
||||
expect(v.full_name).to eq(")))")
|
||||
end
|
||||
end
|
||||
@@ -665,38 +664,16 @@ describe Spree::Variant do
|
||||
end
|
||||
end
|
||||
|
||||
context "when the variant already has a value set (and all required option values do not exist)" do
|
||||
context "when the variant already has a value set" do
|
||||
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar') }
|
||||
|
||||
it "removes the old option value and assigns the new one" do
|
||||
ov_orig = v.option_values.last
|
||||
it "assigns the new option value" do
|
||||
expect(v.unit_presentation).to eq "5g bar"
|
||||
|
||||
expect {
|
||||
v.update!(unit_value: 10, unit_description: 'foo')
|
||||
}.to change(Spree::OptionValue, :count).by(1)
|
||||
v.update!(unit_value: 10, unit_description: 'foo')
|
||||
|
||||
expect(v.option_values).not_to include ov_orig
|
||||
end
|
||||
end
|
||||
|
||||
context "when the variant already has a value set (and all required option values exist)" do
|
||||
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:v0) { create(:variant, product: p0, unit_value: 10, unit_description: 'foo') }
|
||||
|
||||
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
|
||||
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar') }
|
||||
|
||||
it "removes the old option value and assigns the new one" do
|
||||
ov_orig = v.option_values.last
|
||||
ov_new = v0.option_values.last
|
||||
|
||||
expect {
|
||||
v.update!(unit_value: 10, unit_description: 'foo')
|
||||
}.to change(Spree::OptionValue, :count).by(0)
|
||||
|
||||
expect(v.option_values).not_to include ov_orig
|
||||
expect(v.option_values).to include ov_new
|
||||
expect(v.unit_presentation).to eq "10g foo"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -706,11 +683,10 @@ describe Spree::Variant do
|
||||
create(:variant, product: p, unit_value: 5, unit_description: 'bar', display_as: '')
|
||||
}
|
||||
|
||||
it "requests the name of the new option_value from OptionValueName" do
|
||||
it "requests the new value from OptionValueName" do
|
||||
expect_any_instance_of(VariantUnits::OptionValueNamer).to receive(:name).exactly(1).times.and_call_original
|
||||
v.update(unit_value: 10, unit_description: 'foo')
|
||||
ov = v.option_values.last
|
||||
expect(ov.name).to eq("10g foo")
|
||||
expect(v.unit_presentation).to eq "10g foo"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -720,35 +696,14 @@ describe Spree::Variant do
|
||||
create(:variant, product: p, unit_value: 5, unit_description: 'bar', display_as: 'FOOS!')
|
||||
}
|
||||
|
||||
it "does not request the name of the new option_value from OptionValueName" do
|
||||
it "does not request the new value from OptionValueName" do
|
||||
expect_any_instance_of(VariantUnits::OptionValueNamer).not_to receive(:name)
|
||||
v.update!(unit_value: 10, unit_description: 'foo')
|
||||
ov = v.option_values.last
|
||||
expect(ov.name).to eq("FOOS!")
|
||||
expect(v.unit_presentation).to eq("FOOS!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "deleting unit option values" do
|
||||
before do
|
||||
p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1)
|
||||
ot = Spree::OptionType.find_by name: 'unit_weight'
|
||||
@v = create(:variant, product: p)
|
||||
end
|
||||
|
||||
it "removes option value associations for unit option types" do
|
||||
expect {
|
||||
@v.delete_unit_option_values
|
||||
}.to change(@v.option_values, :count).by(-1)
|
||||
end
|
||||
|
||||
it "does not delete option values" do
|
||||
expect {
|
||||
@v.delete_unit_option_values
|
||||
}.to change(Spree::OptionValue, :count).by(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "extends LocalizedNumber" do
|
||||
subject! { build_stubbed(:variant) }
|
||||
|
||||
|
||||
@@ -6,34 +6,35 @@ module VariantUnits
|
||||
describe OptionValueNamer do
|
||||
describe "generating option value name" do
|
||||
let(:v) { Spree::Variant.new }
|
||||
let(:subject) { OptionValueNamer.new }
|
||||
let(:p) { Spree::Product.new }
|
||||
let(:subject) { OptionValueNamer.new(v) }
|
||||
|
||||
it "when description is blank" do
|
||||
allow(v).to receive(:unit_description) { nil }
|
||||
allow(subject).to receive(:value_scaled?) { true }
|
||||
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
|
||||
expect(subject.name(v)).to eq("valueunit")
|
||||
expect(subject.name).to eq("valueunit")
|
||||
end
|
||||
|
||||
it "when description is present" do
|
||||
allow(v).to receive(:unit_description) { 'desc' }
|
||||
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
|
||||
allow(subject).to receive(:value_scaled?) { true }
|
||||
expect(subject.name(v)).to eq("valueunit desc")
|
||||
expect(subject.name).to eq("valueunit desc")
|
||||
end
|
||||
|
||||
it "when value is blank and description is present" do
|
||||
allow(v).to receive(:unit_description) { 'desc' }
|
||||
allow(subject).to receive(:option_value_value_unit) { [nil, nil] }
|
||||
allow(subject).to receive(:value_scaled?) { true }
|
||||
expect(subject.name(v)).to eq("desc")
|
||||
expect(subject.name).to eq("desc")
|
||||
end
|
||||
|
||||
it "spaces value and unit when value is unscaled" do
|
||||
allow(v).to receive(:unit_description) { nil }
|
||||
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
|
||||
allow(subject).to receive(:value_scaled?) { false }
|
||||
expect(subject.name(v)).to eq("value unit")
|
||||
expect(subject.name).to eq("value unit")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,6 +65,7 @@ module VariantUnits
|
||||
it "generates simple values" do
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: 1.0)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 100 }
|
||||
|
||||
expect(subject.send(:option_value_value_unit)).to eq [100, 'g']
|
||||
@@ -72,6 +74,7 @@ module VariantUnits
|
||||
it "generates values when unit value is non-integer" do
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: 1.0)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 123.45 }
|
||||
|
||||
expect(subject.send(:option_value_value_unit)).to eq [123.45, 'g']
|
||||
@@ -80,6 +83,7 @@ module VariantUnits
|
||||
it "returns a value of 1 when unit value equals the scale" do
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: 1000.0)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 1000.0 }
|
||||
|
||||
expect(subject.send(:option_value_value_unit)).to eq [1, 'kg']
|
||||
@@ -88,6 +92,7 @@ module VariantUnits
|
||||
it "returns only values that are in the same measurement systems" do
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: 1.0)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 500 }
|
||||
# 500g would convert to > 1 pound, but we don't want the namer to use
|
||||
# pounds since it's in a different measurement system.
|
||||
@@ -99,6 +104,7 @@ module VariantUnits
|
||||
[1_000_000.0, 'T']].each do |scale, unit|
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: scale)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 10.0 * scale }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [10, unit]
|
||||
end
|
||||
@@ -108,6 +114,7 @@ module VariantUnits
|
||||
[[0.001, 'mL'], [1.0, 'L'], [1000.0, 'kL']].each do |scale, unit|
|
||||
p = double(:product, variant_unit: 'volume', variant_unit_scale: scale)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 100 * scale }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [100, unit]
|
||||
end
|
||||
@@ -116,6 +123,7 @@ module VariantUnits
|
||||
it "chooses the correct scale when value is very small" do
|
||||
p = double(:product, variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 0.0001 }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [0.1, 'mL']
|
||||
end
|
||||
@@ -125,6 +133,7 @@ module VariantUnits
|
||||
p = double(:product, variant_unit: 'items', variant_unit_scale: nil,
|
||||
variant_unit_name: unit)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 100 }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [100, unit.pluralize]
|
||||
end
|
||||
@@ -134,6 +143,7 @@ module VariantUnits
|
||||
p = double(:product, variant_unit: 'items', variant_unit_scale: nil,
|
||||
variant_unit_name: 'packet')
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
allow(v).to receive(:unit_value) { 1 }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [1, 'packet']
|
||||
end
|
||||
@@ -150,6 +160,7 @@ module VariantUnits
|
||||
oz_scale = 28.35
|
||||
p = double(:product, variant_unit: 'weight', variant_unit_scale: oz_scale)
|
||||
allow(v).to receive(:product) { p }
|
||||
allow(p).to receive(:persisted?) { true }
|
||||
# The unit_value is stored rounded to 2 decimals
|
||||
allow(v).to receive(:unit_value) { (12.5 * oz_scale).round(2) }
|
||||
expect(subject.send(:option_value_value_unit)).to eq [BigDecimal(12.5, 6), 'oz']
|
||||
|
||||
@@ -249,7 +249,7 @@ describe '
|
||||
}
|
||||
let!(:li1) { create(:line_item_with_shipment, order: o1) }
|
||||
let!(:li2) {
|
||||
create(:line_item_with_shipment, order: o2, product: create(:product_with_option_types) )
|
||||
create(:line_item_with_shipment, order: o2, product: create(:product) )
|
||||
}
|
||||
|
||||
before :each do
|
||||
@@ -428,8 +428,8 @@ describe '
|
||||
end
|
||||
|
||||
let!(:p1) {
|
||||
create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000,
|
||||
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
|
||||
create(:product, group_buy: true, group_buy_unit_size: 5000,
|
||||
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
|
||||
}
|
||||
let!(:v1) { p1.variants.first }
|
||||
let!(:o1) {
|
||||
@@ -1068,8 +1068,8 @@ describe '
|
||||
let!(:li1) { create(:line_item_with_shipment, order: o1 ) }
|
||||
let!(:li2) { create(:line_item_with_shipment, order: o2 ) }
|
||||
let!(:p3) {
|
||||
create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000,
|
||||
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
|
||||
create(:product, group_buy: true, group_buy_unit_size: 5000,
|
||||
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
|
||||
}
|
||||
let!(:v3) { p3.variants.first }
|
||||
let!(:o3) {
|
||||
|
||||
@@ -113,8 +113,7 @@ describe '
|
||||
expect(product.shipping_category).to eq(shipping_category)
|
||||
expect(product.description).to eq("<p>A description...</p>")
|
||||
expect(product.group_buy).to be_falsey
|
||||
expect(product.master.option_values.map(&:name)).to eq(['5kg'])
|
||||
expect(product.master.options_text).to eq("5kg")
|
||||
expect(product.master.unit_presentation).to eq("5kg")
|
||||
end
|
||||
|
||||
it "creating an on-demand product" do
|
||||
|
||||
@@ -237,12 +237,12 @@ describe "Orders And Fulfillment" do
|
||||
table = rows.map { |r| r.all("td").map { |c| c.text.strip } }
|
||||
|
||||
expect(table).to include [
|
||||
"Supplier Name", "Baked Beans", "1g Big, S",
|
||||
"Supplier Name", "Baked Beans", "1g Big",
|
||||
"3", "0.003", "10.0", "30.0"
|
||||
]
|
||||
|
||||
expect(table).to include [
|
||||
"Supplier Name", "Baked Beans", "1g Small, S",
|
||||
"Supplier Name", "Baked Beans", "1g Small",
|
||||
"7", "0.007", "10.0", "70.0"
|
||||
]
|
||||
expect(table[2]).to eq [
|
||||
|
||||
@@ -380,8 +380,6 @@ describe '
|
||||
variant2.update!(sku: "sku2")
|
||||
variant3.on_hand = 9
|
||||
variant3.update!(sku: "")
|
||||
variant1.option_values = [create(:option_value, presentation: "Test")]
|
||||
variant2.option_values = [create(:option_value, presentation: "Something")]
|
||||
end
|
||||
|
||||
it "shows products and inventory report" do
|
||||
@@ -399,12 +397,12 @@ describe '
|
||||
expect(page).to have_table_row [product1.supplier.name, product1.supplier.address.city,
|
||||
"Product Name",
|
||||
product1.properties.map(&:presentation).join(", "),
|
||||
product1.primary_taxon.name, "Test", "100.0",
|
||||
product1.primary_taxon.name, "1g", "100.0",
|
||||
"none", "", "sku1"]
|
||||
expect(page).to have_table_row [product1.supplier.name, product1.supplier.address.city,
|
||||
"Product Name",
|
||||
product1.properties.map(&:presentation).join(", "),
|
||||
product1.primary_taxon.name, "Something", "80.0",
|
||||
product1.primary_taxon.name, "1g", "80.0",
|
||||
"none", "", "sku2"]
|
||||
expect(page).to have_table_row [product2.supplier.name, product1.supplier.address.city,
|
||||
"Product 2",
|
||||
|
||||
@@ -209,11 +209,11 @@ describe 'Subscriptions' do
|
||||
}
|
||||
let!(:test_product) { create(:product, supplier: shop) }
|
||||
let!(:test_variant) {
|
||||
create(:variant, product: test_product, unit_value: "100", price: 12.00, option_values: [])
|
||||
create(:variant, product: test_product, unit_value: "100", price: 12.00)
|
||||
}
|
||||
let!(:shop_product) { create(:product, supplier: shop) }
|
||||
let!(:shop_variant) {
|
||||
create(:variant, product: shop_product, unit_value: "1000", price: 6.00, option_values: [])
|
||||
create(:variant, product: shop_product, unit_value: "1000", price: 6.00)
|
||||
}
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle) {
|
||||
@@ -453,13 +453,13 @@ describe 'Subscriptions' do
|
||||
let!(:product2) { create(:product, supplier: shop) }
|
||||
let!(:product3) { create(:product, supplier: shop) }
|
||||
let!(:variant1) {
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00)
|
||||
}
|
||||
let!(:variant2) {
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00)
|
||||
}
|
||||
let!(:variant3) {
|
||||
create(:variant, product: product3, unit_value: '10000', price: 22.00, option_values: [])
|
||||
create(:variant, product: product3, unit_value: '10000', price: 22.00)
|
||||
}
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle) {
|
||||
@@ -606,10 +606,10 @@ describe 'Subscriptions' do
|
||||
let!(:product1) { create(:product, supplier: shop) }
|
||||
let!(:product2) { create(:product, supplier: shop) }
|
||||
let!(:variant1) {
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
|
||||
create(:variant, product: product1, unit_value: '100', price: 12.00)
|
||||
}
|
||||
let!(:variant2) {
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
|
||||
create(:variant, product: product2, unit_value: '1000', price: 6.00)
|
||||
}
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle) {
|
||||
|
||||
@@ -74,11 +74,6 @@ describe "
|
||||
|
||||
let!(:product_unrelated) { create(:simple_product, supplier: producer_unrelated) }
|
||||
|
||||
before do
|
||||
# Remove 'S' option value
|
||||
variant.option_values.first.destroy
|
||||
end
|
||||
|
||||
context "when a hub is selected" do
|
||||
before do
|
||||
visit '/admin/inventory'
|
||||
|
||||
@@ -127,9 +127,6 @@ describe '
|
||||
variant = product.variants.first
|
||||
variant.update( unit_value: 1, unit_description: 'foo' )
|
||||
|
||||
# And the product has option types for the unit-related and non-unit-related option values
|
||||
product.option_types << variant.option_values.first.option_type
|
||||
|
||||
# When I view the variant
|
||||
login_as_admin
|
||||
visit spree.admin_product_variants_path product
|
||||
|
||||
Reference in New Issue
Block a user