mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-17 00:07:24 +00:00
Remove master variant from product
This commit is contained in:
@@ -33,6 +33,4 @@ angular.module('admin.orderCycles').factory('Enterprise', ($resource) ->
|
||||
variantsOf: (product) ->
|
||||
if product.variants.length > 0
|
||||
variant.id for variant in product.variants
|
||||
else
|
||||
[product.master_id]
|
||||
})
|
||||
|
||||
@@ -56,9 +56,9 @@ module Api
|
||||
def scope
|
||||
if @product
|
||||
variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
@product.variants_including_master.with_deleted
|
||||
@product.variants.with_deleted
|
||||
else
|
||||
@product.variants_including_master
|
||||
@product.variants
|
||||
end
|
||||
else
|
||||
variants = Spree::Variant.where(nil)
|
||||
|
||||
@@ -81,10 +81,6 @@ module Spree
|
||||
|
||||
def load_data
|
||||
@product = Product.find_by(permalink: params[:product_id])
|
||||
@variants = @product.variants.collect do |variant|
|
||||
[variant.options_text, variant.id]
|
||||
end
|
||||
@variants.insert(0, [Spree.t(:all), @product.master.id])
|
||||
end
|
||||
|
||||
def set_viewable
|
||||
|
||||
@@ -121,8 +121,7 @@ module Spree
|
||||
end
|
||||
|
||||
def product_includes
|
||||
[:image, { variants: [:images] },
|
||||
{ master: [:default_price] }]
|
||||
[:image, { variants: [:images] }]
|
||||
end
|
||||
|
||||
def collection_actions
|
||||
@@ -229,11 +228,9 @@ module Spree
|
||||
end
|
||||
|
||||
def product_variant(product)
|
||||
if product.variants.any?
|
||||
product.variants.first
|
||||
else
|
||||
product.master
|
||||
end
|
||||
return unless product.variants.any?
|
||||
|
||||
product.variants.first
|
||||
end
|
||||
|
||||
def set_product_master_variant_price_to_zero
|
||||
|
||||
@@ -7,8 +7,6 @@ module Spree
|
||||
class VariantsController < ::Admin::ResourceController
|
||||
belongs_to 'spree/product', find_by: :permalink
|
||||
|
||||
before_action :assign_default_attributes, only: :new
|
||||
|
||||
def index
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
@@ -83,11 +81,6 @@ module Spree
|
||||
@object.save
|
||||
end
|
||||
|
||||
def assign_default_attributes
|
||||
@object.attributes = @object.product.master.
|
||||
attributes.except('id', 'created_at', 'deleted_at', 'sku', 'is_master')
|
||||
end
|
||||
|
||||
def collection
|
||||
@deleted = params.key?(:deleted) && params[:deleted] == "on" ? "checked" : ""
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ class Enterprise < ApplicationRecord
|
||||
scope :is_distributor, -> { where('sells != ?', 'none') }
|
||||
scope :is_hub, -> { where(sells: 'any') }
|
||||
scope :supplying_variant_in, lambda { |variants|
|
||||
joins(supplied_products: :variants_including_master).
|
||||
joins(supplied_products: :variants).
|
||||
where('spree_variants.id IN (?)', variants).
|
||||
select('DISTINCT enterprises.*')
|
||||
}
|
||||
@@ -389,7 +389,7 @@ class Enterprise < ApplicationRecord
|
||||
def current_distributed_taxons
|
||||
Spree::Taxon
|
||||
.select("DISTINCT spree_taxons.*")
|
||||
.joins(products: :variants_including_master)
|
||||
.joins(products: :variants)
|
||||
.joins("INNER JOIN (#{current_exchange_variants.to_sql}) \
|
||||
AS exchange_variants ON spree_variants.id = exchange_variants.variant_id")
|
||||
end
|
||||
|
||||
@@ -55,7 +55,7 @@ class Exchange < ApplicationRecord
|
||||
}
|
||||
scope :with_product, lambda { |product|
|
||||
joins(:exchange_variants).
|
||||
where('exchange_variants.variant_id IN (?)', product.variants_including_master.select(&:id))
|
||||
where('exchange_variants.variant_id IN (?)', product.variants.select(&:id))
|
||||
}
|
||||
scope :by_enterprise_name, -> {
|
||||
joins('INNER JOIN enterprises AS sender ON (sender.id = exchanges.sender_id)').
|
||||
|
||||
@@ -29,7 +29,7 @@ module Spree
|
||||
acts_as_paranoid
|
||||
|
||||
searchable_attributes :supplier_id, :primary_taxon_id, :meta_keywords
|
||||
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
|
||||
searchable_associations :supplier, :properties, :primary_taxon, :variants
|
||||
searchable_scopes :active, :with_properties
|
||||
|
||||
has_many :product_properties, dependent: :destroy
|
||||
@@ -45,19 +45,9 @@ module Spree
|
||||
|
||||
has_one :image, class_name: "Spree::Image", as: :viewable, dependent: :destroy
|
||||
|
||||
has_one :master,
|
||||
-> { where is_master: true },
|
||||
class_name: 'Spree::Variant',
|
||||
dependent: :destroy
|
||||
|
||||
has_many :variants, -> {
|
||||
where(is_master: false).order("spree_variants.position ASC")
|
||||
}, class_name: 'Spree::Variant'
|
||||
|
||||
has_many :variants_including_master,
|
||||
-> { order("spree_variants.position ASC") },
|
||||
class_name: 'Spree::Variant',
|
||||
dependent: :destroy
|
||||
}, class_name: 'Spree::Variant', dependent: :destroy
|
||||
|
||||
has_many :prices, -> {
|
||||
order('spree_variants.position, spree_variants.id, currency')
|
||||
@@ -81,11 +71,8 @@ module Spree
|
||||
# these values are persisted on the product's variant
|
||||
attr_accessor :price, :display_as, :unit_value, :unit_description
|
||||
|
||||
after_create :set_master_variant_defaults
|
||||
after_save :save_master
|
||||
|
||||
has_many :variant_images, -> { order(:position) }, source: :images,
|
||||
through: :variants_including_master
|
||||
through: :variants
|
||||
|
||||
accepts_nested_attributes_for :variants, allow_destroy: true
|
||||
accepts_nested_attributes_for :image
|
||||
@@ -114,13 +101,12 @@ module Spree
|
||||
|
||||
make_permalink order: :name
|
||||
|
||||
after_initialize :ensure_master
|
||||
after_initialize :set_available_on_to_now, if: :new_record?
|
||||
|
||||
before_validation :sanitize_permalink
|
||||
before_save :add_primary_taxon_to_taxons
|
||||
after_save :remove_previous_primary_taxon_from_taxons
|
||||
after_save :ensure_standard_variant
|
||||
after_create :ensure_standard_variant
|
||||
after_save :update_units
|
||||
|
||||
before_destroy :punch_permalink
|
||||
@@ -149,7 +135,7 @@ module Spree
|
||||
}
|
||||
|
||||
scope :with_order_cycles_inner, -> {
|
||||
joins(variants_including_master: { exchanges: :order_cycle })
|
||||
joins(variants: { exchanges: :order_cycle })
|
||||
}
|
||||
|
||||
scope :visible_for, lambda { |enterprise|
|
||||
@@ -282,13 +268,6 @@ module Spree
|
||||
stock_items.sum(&:count_on_hand)
|
||||
end
|
||||
|
||||
# Master variant may be deleted (i.e. when the product is deleted)
|
||||
# which would make AR's default finder return nil.
|
||||
# This is a stopgap for that little problem.
|
||||
def master
|
||||
super || variants_including_master.with_deleted.find_by(is_master: true)
|
||||
end
|
||||
|
||||
def properties_including_inherited
|
||||
# Product properties override producer properties
|
||||
ps = product_properties.all
|
||||
@@ -324,7 +303,7 @@ module Spree
|
||||
touch_distributors
|
||||
|
||||
ExchangeVariant.
|
||||
where('exchange_variants.variant_id IN (?)', variants_including_master.with_deleted.
|
||||
where('exchange_variants.variant_id IN (?)', variants.with_deleted.
|
||||
select(:id)).destroy_all
|
||||
|
||||
super
|
||||
@@ -333,33 +312,6 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
# ensures the master variant is flagged as such
|
||||
def set_master_variant_defaults
|
||||
master.is_master = true
|
||||
end
|
||||
|
||||
# Here we rescue errors when saving master variants (without the need for a
|
||||
# validates_associated on master) and we get more specific data about the errors
|
||||
def save_master
|
||||
if master && (master.changed? || master.new_record?)
|
||||
master.save!
|
||||
end
|
||||
|
||||
# If the master cannot be saved, the Product object will get its errors
|
||||
# and will be destroyed
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
master.errors.each do |error|
|
||||
errors.add error.attribute, error.message
|
||||
end
|
||||
raise
|
||||
end
|
||||
|
||||
def ensure_master
|
||||
return unless new_record?
|
||||
|
||||
self.master ||= Variant.new
|
||||
end
|
||||
|
||||
def punch_permalink
|
||||
# Punch permalink with date prefix
|
||||
update_attribute :permalink, "#{Time.now.to_i}_#{permalink}"
|
||||
@@ -372,7 +324,7 @@ module Spree
|
||||
def update_units
|
||||
return unless saved_change_to_variant_unit? || saved_change_to_variant_unit_name?
|
||||
|
||||
variants_including_master.each(&:update_units)
|
||||
variants.each(&:update_units)
|
||||
end
|
||||
|
||||
def touch_distributors
|
||||
@@ -390,11 +342,10 @@ module Spree
|
||||
end
|
||||
|
||||
def ensure_standard_variant
|
||||
return unless master.valid? && variants.empty?
|
||||
return unless variants.empty?
|
||||
|
||||
variant = master.dup
|
||||
variant = Spree::Variant.new
|
||||
variant.product = self
|
||||
variant.is_master = false
|
||||
variant.price = price
|
||||
variant.display_as = display_as
|
||||
variant.unit_value = unit_value
|
||||
|
||||
@@ -79,7 +79,7 @@ module Spree
|
||||
|
||||
taxons = Spree::Taxon
|
||||
.select("DISTINCT spree_taxons.id, ents_and_vars.enterprise_id")
|
||||
.joins(products: :variants_including_master)
|
||||
.joins(products: :variants)
|
||||
.joins("
|
||||
INNER JOIN (#{ents_and_vars.to_sql}) AS ents_and_vars
|
||||
ON spree_variants.id = ents_and_vars.variant_id")
|
||||
|
||||
@@ -4,7 +4,7 @@ module Api
|
||||
module Admin
|
||||
module ForOrderCycle
|
||||
class SuppliedProductSerializer < ActiveModel::Serializer
|
||||
attributes :name, :supplier_name, :image_url, :master_id, :variants
|
||||
attributes :name, :supplier_name, :image_url, :variants
|
||||
|
||||
def supplier_name
|
||||
object.supplier&.name
|
||||
@@ -14,10 +14,6 @@ module Api
|
||||
object.image&.url(:mini)
|
||||
end
|
||||
|
||||
def master_id
|
||||
object.master.id
|
||||
end
|
||||
|
||||
def variants
|
||||
variants = if order_cycle.present? &&
|
||||
order_cycle.prefers_product_selection_from_coordinator_inventory_only?
|
||||
|
||||
@@ -5,7 +5,7 @@ module Api
|
||||
class ProductSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :sku, :variant_unit, :variant_unit_scale, :variant_unit_name,
|
||||
:inherits_properties, :on_hand, :price, :available_on, :permalink_live,
|
||||
:tax_category_id, :import_date, :image_url, :thumb_url, :variants, :master
|
||||
:tax_category_id, :import_date, :image_url, :thumb_url, :variants
|
||||
|
||||
has_one :supplier, key: :producer_id, embed: :id
|
||||
has_one :primary_taxon, key: :category_id, embed: :id
|
||||
@@ -19,13 +19,6 @@ module Api
|
||||
)
|
||||
end
|
||||
|
||||
def master
|
||||
Api::Admin::VariantSerializer.new(
|
||||
object.master,
|
||||
image: thumb_url
|
||||
)
|
||||
end
|
||||
|
||||
def image_url
|
||||
object.image&.url(:product) || Spree::Image.default_image_url(:product)
|
||||
end
|
||||
|
||||
@@ -100,7 +100,7 @@ module Sets
|
||||
end
|
||||
|
||||
def create_or_update_variant(product, variant_attributes)
|
||||
variant = find_model(product.variants_including_master, variant_attributes[:id])
|
||||
variant = find_model(product.variants, variant_attributes[:id])
|
||||
if variant.present?
|
||||
variant.update(variant_attributes.except(:id))
|
||||
else
|
||||
|
||||
@@ -13,7 +13,7 @@ describe "Enterprises", type: :request do
|
||||
|
||||
expect(response).to have_http_status :ok
|
||||
expect(response.body).to include(product.name)
|
||||
expect(response.body).to include(product.sku)
|
||||
expect(response.body).to include(product.variants.first.sku)
|
||||
expect(response.body).to include("offers/#{product.variants.first.id}")
|
||||
end
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ module OpenFoodNetwork
|
||||
@order_cycle
|
||||
).pluck(:id).uniq
|
||||
|
||||
product_ids = Spree::Product.joins(:variants_including_master).
|
||||
product_ids = Spree::Product.joins(:variants).
|
||||
where("spree_variants.id IN (?)", variant_ids).pluck(:id).uniq
|
||||
|
||||
producers_active_ids = Enterprise.joins(:supplied_products).
|
||||
@@ -304,7 +304,7 @@ module OpenFoodNetwork
|
||||
hubs.select("enterprises.id"),
|
||||
@order_cycle).pluck(:id).uniq
|
||||
|
||||
product_ids = Spree::Product.joins(:variants_including_master).
|
||||
product_ids = Spree::Product.joins(:variants).
|
||||
where(spree_variants: { id: variant_ids }).pluck(:id).uniq
|
||||
|
||||
producer_ids = Enterprise.joins(:supplied_products).
|
||||
|
||||
@@ -25,17 +25,11 @@ module Spree
|
||||
new_product.deleted_at = nil
|
||||
new_product.updated_at = nil
|
||||
new_product.product_properties = reset_properties
|
||||
new_product.master = duplicate_master
|
||||
new_product.image = duplicate_image(product.image) if product.image&.attached?
|
||||
new_product.image = duplicate_image(product.image) if product.image
|
||||
new_product.variants = duplicate_variants
|
||||
end
|
||||
end
|
||||
|
||||
def duplicate_master
|
||||
master = product.master
|
||||
duplicate_variant(master)
|
||||
end
|
||||
|
||||
def duplicate_variants
|
||||
product.variants.map do |variant|
|
||||
duplicate_variant(variant)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace :ofn do
|
||||
end
|
||||
|
||||
# For each variant in the exchange
|
||||
products = Spree::Product.joins(:variants_including_master).where(
|
||||
products = Spree::Product.joins(:variants).where(
|
||||
'spree_variants.id IN (?)', exchange.variants
|
||||
).pluck(:id).uniq
|
||||
producers = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)",
|
||||
|
||||
@@ -24,13 +24,13 @@ describe Admin::ReportsController, type: :controller do
|
||||
create(:simple_order_cycle, coordinator: coordinator1,
|
||||
distributors: [distributor1, distributor2],
|
||||
suppliers: [supplier1, supplier2, supplier3],
|
||||
variants: [product1.master, product3.master])
|
||||
variants: [product1.variants.first, product3.variants.first])
|
||||
}
|
||||
let(:ocB) {
|
||||
create(:simple_order_cycle, coordinator: coordinator2,
|
||||
distributors: [distributor1, distributor2],
|
||||
suppliers: [supplier1, supplier2, supplier3],
|
||||
variants: [product2.master])
|
||||
variants: [product2.variants.first])
|
||||
}
|
||||
|
||||
# orderA1 can only be accessed by supplier1, supplier3 and distributor1
|
||||
@@ -38,8 +38,8 @@ describe Admin::ReportsController, type: :controller do
|
||||
order = create(:order, distributor: distributor1, bill_address: bill_address,
|
||||
ship_address: ship_address, special_instructions: instructions,
|
||||
order_cycle: ocA)
|
||||
order.line_items << create(:line_item, variant: product1.master)
|
||||
order.line_items << create(:line_item, variant: product3.master)
|
||||
order.line_items << create(:line_item, variant: product1.variants.first)
|
||||
order.line_items << create(:line_item, variant: product3.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
@@ -49,7 +49,7 @@ describe Admin::ReportsController, type: :controller do
|
||||
order = create(:order, distributor: distributor2, bill_address: bill_address,
|
||||
ship_address: ship_address, special_instructions: instructions,
|
||||
order_cycle: ocA)
|
||||
order.line_items << create(:line_item, variant: product2.master)
|
||||
order.line_items << create(:line_item, variant: product2.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
@@ -59,8 +59,8 @@ describe Admin::ReportsController, type: :controller do
|
||||
order = create(:order, distributor: distributor1, bill_address: bill_address,
|
||||
ship_address: ship_address, special_instructions: instructions,
|
||||
order_cycle: ocB)
|
||||
order.line_items << create(:line_item, variant: product1.master)
|
||||
order.line_items << create(:line_item, variant: product3.master)
|
||||
order.line_items << create(:line_item, variant: product1.variants.first)
|
||||
order.line_items << create(:line_item, variant: product3.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
@@ -70,7 +70,7 @@ describe Admin::ReportsController, type: :controller do
|
||||
order = create(:order, distributor: distributor2, bill_address: bill_address,
|
||||
ship_address: ship_address, special_instructions: instructions,
|
||||
order_cycle: ocB)
|
||||
order.line_items << create(:line_item, variant: product2.master)
|
||||
order.line_items << create(:line_item, variant: product2.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
|
||||
@@ -208,13 +208,6 @@ describe Api::V0::ProductsController, type: :controller do
|
||||
spree_post :clone, product_id: product.id, format: :json
|
||||
expect(Spree::Product.second.variants.count).not_to eq Spree::Product.first.variants.count
|
||||
end
|
||||
|
||||
# price info: it does not consider price changes; it considers the price set upon product creation
|
||||
it '(does not) clone master price which was updated' do
|
||||
product.master.update_attribute(:price, 2.22)
|
||||
spree_post :clone, product_id: product.id, format: :json
|
||||
expect(json_response['price']).not_to eq(2.22)
|
||||
end
|
||||
end
|
||||
|
||||
context 'as an administrator' do
|
||||
|
||||
@@ -32,8 +32,8 @@ FactoryBot.define do
|
||||
proxy.exchanges.incoming.each do |exchange|
|
||||
product = create(:product, supplier: exchange.sender)
|
||||
Spree::Image.create(
|
||||
viewable_id: product.master.id,
|
||||
viewable_type: 'Spree::Variant',
|
||||
viewable_id: product.id,
|
||||
viewable_type: 'Spree::Product',
|
||||
alt: "position 1",
|
||||
attachment: Rack::Test::UploadedFile.new(white_logo_path),
|
||||
position: 1
|
||||
|
||||
@@ -32,7 +32,6 @@ FactoryBot.define do
|
||||
tax_category { |r| Spree::TaxCategory.first || r.association(:tax_category) }
|
||||
|
||||
after(:create) do |product, evaluator|
|
||||
product.master.on_hand = evaluator.on_hand
|
||||
product.variants.first.on_hand = evaluator.on_hand
|
||||
product.reload
|
||||
end
|
||||
@@ -53,8 +52,6 @@ FactoryBot.define do
|
||||
on_hand { 5 }
|
||||
end
|
||||
after(:create) do |product, evaluator|
|
||||
product.master.on_demand = evaluator.on_demand
|
||||
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
|
||||
|
||||
@@ -27,8 +27,8 @@ FactoryBot.define do
|
||||
product_1 = create(:product)
|
||||
product_2 = create(:product)
|
||||
|
||||
stock_location.stock_items.where(variant_id: product_1.master.id).first.adjust_count_on_hand(10)
|
||||
stock_location.stock_items.where(variant_id: product_2.master.id).first.adjust_count_on_hand(20)
|
||||
stock_location.stock_items.where(variant_id: product_1.variants.first.id).first.adjust_count_on_hand(10)
|
||||
stock_location.stock_items.where(variant_id: product_2.variants.first.id).first.adjust_count_on_hand(20)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,14 +45,7 @@ describe 'Enterprise service', ->
|
||||
expect(Enterprise.suppliedVariants(1)).toEqual [10, 10]
|
||||
|
||||
describe "finding the variants of a product", ->
|
||||
it "returns the master for products without variants", ->
|
||||
p =
|
||||
master_id: 1
|
||||
variants: []
|
||||
expect(Enterprise.variantsOf(p)).toEqual [1]
|
||||
|
||||
it "returns the variant ids for products with variants", ->
|
||||
p =
|
||||
master_id: 1
|
||||
variants: [{id: 2}, {id: 3}]
|
||||
expect(Enterprise.variantsOf(p)).toEqual [2, 3]
|
||||
|
||||
@@ -25,32 +25,32 @@ module OpenFoodNetwork
|
||||
describe "supplier fees" do
|
||||
let!(:exchange1) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: supplier1, receiver: coordinator, incoming: true,
|
||||
enterprise_fees: [enterprise_fee1], variants: [product1.master])
|
||||
enterprise_fees: [enterprise_fee1], variants: [product1.variants.first])
|
||||
}
|
||||
let!(:exchange2) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: supplier2, receiver: coordinator, incoming: true,
|
||||
enterprise_fees: [enterprise_fee2], variants: [product2.master])
|
||||
enterprise_fees: [enterprise_fee2], variants: [product2.variants.first])
|
||||
}
|
||||
|
||||
it "calculates via regular computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_for(product1.master)).to eq(20)
|
||||
order_cycle).fees_for(product1.variants.first)).to eq(20)
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_for(product2.master)).to eq(3)
|
||||
order_cycle).fees_for(product2.variants.first)).to eq(3)
|
||||
end
|
||||
|
||||
it "calculates via indexed computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_for(product1.master)).to eq(20)
|
||||
order_cycle).indexed_fees_for(product1.variants.first)).to eq(20)
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_for(product2.master)).to eq(3)
|
||||
order_cycle).indexed_fees_for(product2.variants.first)).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "coordinator fees" do
|
||||
let!(:exchange) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: distributor, incoming: false,
|
||||
enterprise_fees: [], variants: [product1.master])
|
||||
enterprise_fees: [], variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
before do
|
||||
@@ -59,29 +59,29 @@ module OpenFoodNetwork
|
||||
|
||||
it "sums via regular computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_for(product1.master)).to eq(23)
|
||||
order_cycle).fees_for(product1.variants.first)).to eq(23)
|
||||
end
|
||||
|
||||
it "sums via indexed computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_for(product1.master)).to eq(23)
|
||||
order_cycle).indexed_fees_for(product1.variants.first)).to eq(23)
|
||||
end
|
||||
end
|
||||
|
||||
describe "distributor fees" do
|
||||
let!(:exchange) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: distributor, incoming: false,
|
||||
enterprise_fees: [enterprise_fee1, enterprise_fee2, enterprise_fee3], variants: [product1.master])
|
||||
enterprise_fees: [enterprise_fee1, enterprise_fee2, enterprise_fee3], variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
it "sums via regular computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_for(product1.master)).to eq(23)
|
||||
order_cycle).fees_for(product1.variants.first)).to eq(23)
|
||||
end
|
||||
|
||||
it "sums via indexed computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_for(product1.master)).to eq(23)
|
||||
order_cycle).indexed_fees_for(product1.variants.first)).to eq(23)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -93,17 +93,17 @@ module OpenFoodNetwork
|
||||
}
|
||||
let!(:exchange) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: distributor, incoming: false,
|
||||
enterprise_fees: [enterprise_fee1], variants: [product1.master])
|
||||
enterprise_fees: [enterprise_fee1], variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
it "sums via regular computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_for(product1.master)).to eq(2.00)
|
||||
order_cycle).fees_for(product1.variants.first)).to eq(2.00)
|
||||
end
|
||||
|
||||
it "sums via indexed computation" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_for(product1.master)).to eq(2.00)
|
||||
order_cycle).indexed_fees_for(product1.variants.first)).to eq(2.00)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -123,27 +123,27 @@ module OpenFoodNetwork
|
||||
enterprise_fees: [
|
||||
ef_admin, ef_sales, ef_packing, ef_transport, ef_fundraising
|
||||
],
|
||||
variants: [product1.master])
|
||||
variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
describe "regular computation" do
|
||||
it "returns the fees names" do
|
||||
expect(EnterpriseFeeCalculator
|
||||
.new(distributor, order_cycle).fees_name_by_type_for(product1.master))
|
||||
.new(distributor, order_cycle).fees_name_by_type_for(product1.variants.first))
|
||||
.to eq({ admin: "Admin", fundraising: "Fundraising", packing: "Packing",
|
||||
sales: "Sales", transport: "Transport" })
|
||||
end
|
||||
|
||||
it "returns a breakdown of fees" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_by_type_for(product1.master)).to eq(admin: 1.23, sales: 4.56, packing: 7.89,
|
||||
order_cycle).fees_by_type_for(product1.variants.first)).to eq(admin: 1.23, sales: 4.56, packing: 7.89,
|
||||
transport: 0.12, fundraising: 3.45)
|
||||
end
|
||||
|
||||
it "filters out zero fees" do
|
||||
ef_admin.calculator.update_attribute :preferred_amount, 0
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).fees_by_type_for(product1.master)).to eq(sales: 4.56, packing: 7.89, transport: 0.12,
|
||||
order_cycle).fees_by_type_for(product1.variants.first)).to eq(sales: 4.56, packing: 7.89, transport: 0.12,
|
||||
fundraising: 3.45)
|
||||
end
|
||||
end
|
||||
@@ -151,14 +151,14 @@ module OpenFoodNetwork
|
||||
describe "indexed computation" do
|
||||
it "returns a breakdown of fees" do
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_by_type_for(product1.master)).to eq(admin: 1.23, sales: 4.56,
|
||||
order_cycle).indexed_fees_by_type_for(product1.variants.first)).to eq(admin: 1.23, sales: 4.56,
|
||||
packing: 7.89, transport: 0.12, fundraising: 3.45)
|
||||
end
|
||||
|
||||
it "filters out zero fees" do
|
||||
ef_admin.calculator.update_attribute :preferred_amount, 0
|
||||
expect(EnterpriseFeeCalculator.new(distributor,
|
||||
order_cycle).indexed_fees_by_type_for(product1.master)).to eq(sales: 4.56, packing: 7.89,
|
||||
order_cycle).indexed_fees_by_type_for(product1.variants.first)).to eq(sales: 4.56, packing: 7.89,
|
||||
transport: 0.12, fundraising: 3.45)
|
||||
end
|
||||
end
|
||||
@@ -166,14 +166,14 @@ module OpenFoodNetwork
|
||||
|
||||
describe "creating adjustments" do
|
||||
let(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) }
|
||||
let!(:line_item) { create(:line_item, order: order, variant: product1.master) }
|
||||
let!(:line_item) { create(:line_item, order: order, variant: product1.variants.first) }
|
||||
let(:enterprise_fee_line_item) { create(:enterprise_fee) }
|
||||
let(:enterprise_fee_order) {
|
||||
create(:enterprise_fee, calculator: Calculator::FlatRate.new(preferred_amount: 2))
|
||||
}
|
||||
let!(:exchange) {
|
||||
create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: distributor,
|
||||
incoming: false, variants: [product1.master])
|
||||
incoming: false, variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
before { order.reload }
|
||||
|
||||
@@ -30,8 +30,8 @@ describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
let(:params) { { q: "product 1" } }
|
||||
|
||||
it "returns all products whose names or SKUs match the query" do
|
||||
expect(result).to include v1, v2
|
||||
expect(result).to_not include v3, v4
|
||||
expect(result).to include v1
|
||||
expect(result).to_not include v2, v3, v4
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ describe Spree::Core::ProductDuplicator do
|
||||
name: "foo",
|
||||
taxons: [],
|
||||
product_properties: [property],
|
||||
master: master_variant,
|
||||
variants: [variant]
|
||||
variants: [variant],
|
||||
image: image
|
||||
end
|
||||
|
||||
let(:new_product) do
|
||||
@@ -25,14 +25,6 @@ describe Spree::Core::ProductDuplicator do
|
||||
double 'New Property'
|
||||
end
|
||||
|
||||
let(:master_variant) do
|
||||
double 'Variant',
|
||||
sku: "12345",
|
||||
price: 19.99,
|
||||
currency: "AUD",
|
||||
images: [image]
|
||||
end
|
||||
|
||||
let(:variant) do
|
||||
double 'Variant 1',
|
||||
sku: "67890",
|
||||
@@ -41,11 +33,6 @@ describe Spree::Core::ProductDuplicator do
|
||||
images: [image_variant]
|
||||
end
|
||||
|
||||
let(:new_master_variant) do
|
||||
double 'New Variant',
|
||||
sku: "12345"
|
||||
end
|
||||
|
||||
let(:new_variant) do
|
||||
double 'New Variant 1',
|
||||
sku: "67890"
|
||||
@@ -72,7 +59,6 @@ describe Spree::Core::ProductDuplicator do
|
||||
|
||||
before do
|
||||
expect(product).to receive(:dup).and_return(new_product)
|
||||
expect(master_variant).to receive(:dup).and_return(new_master_variant)
|
||||
expect(variant).to receive(:dup).and_return(new_variant)
|
||||
expect(image).to receive(:dup).and_return(new_image)
|
||||
expect(image_variant).to receive(:dup).and_return(new_image_variant)
|
||||
@@ -88,14 +74,8 @@ describe Spree::Core::ProductDuplicator do
|
||||
expect(new_product).to receive(:unit_value=).with(true)
|
||||
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(:variants=).with([new_variant])
|
||||
|
||||
expect(new_master_variant).to receive(:sku=).with("")
|
||||
expect(new_master_variant).to receive(:deleted_at=).with(nil)
|
||||
expect(new_master_variant).to receive(:images=).with([new_image])
|
||||
expect(new_master_variant).to receive(:price=).with(master_variant.price)
|
||||
expect(new_master_variant).to receive(:currency=).with(master_variant.currency)
|
||||
expect(new_product).to receive(:image=).with(new_image)
|
||||
|
||||
expect(new_variant).to receive(:sku=).with("")
|
||||
expect(new_variant).to receive(:deleted_at=).with(nil)
|
||||
|
||||
@@ -5,25 +5,6 @@ require "spec_helper"
|
||||
describe ProductStock do
|
||||
let(:product) { create(:simple_product) }
|
||||
|
||||
context "when product has no variants" do
|
||||
before do
|
||||
product.variants.destroy
|
||||
product.variants.reload
|
||||
end
|
||||
|
||||
describe "product.on_demand" do
|
||||
it "is master.on_demand" do
|
||||
expect(product.on_demand).to eq(product.master.on_demand)
|
||||
end
|
||||
end
|
||||
|
||||
describe "product.on_hand" do
|
||||
it "is master.on_hand" do
|
||||
expect(product.on_hand).to eq(product.master.on_hand)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when product has one variant" do
|
||||
describe "product.on_demand" do
|
||||
it "is the products first variant on_demand" do
|
||||
|
||||
@@ -487,7 +487,7 @@ describe Enterprise do
|
||||
s = create(:supplier_enterprise)
|
||||
d = create(:distributor_enterprise)
|
||||
p = create(:product)
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.variants.first])
|
||||
expect(Enterprise.distributors_with_active_order_cycles).to eq([d])
|
||||
end
|
||||
|
||||
@@ -496,19 +496,12 @@ describe Enterprise do
|
||||
d = create(:distributor_enterprise)
|
||||
p = create(:product)
|
||||
create(:simple_order_cycle, orders_open_at: 10.days.from_now,
|
||||
orders_close_at: 17.days.from_now, suppliers: [s], distributors: [d], variants: [p.master])
|
||||
orders_close_at: 17.days.from_now, suppliers: [s], distributors: [d], variants: [p.variants.first])
|
||||
expect(Enterprise.distributors_with_active_order_cycles).not_to include d
|
||||
end
|
||||
end
|
||||
|
||||
describe "supplying_variant_in" do
|
||||
it "finds producers by supply of master variant" do
|
||||
s = create(:supplier_enterprise)
|
||||
p = create(:simple_product, supplier: s)
|
||||
|
||||
expect(Enterprise.supplying_variant_in([p.master])).to eq([s])
|
||||
end
|
||||
|
||||
it "finds producers by supply of variant" do
|
||||
s = create(:supplier_enterprise)
|
||||
p = create(:simple_product, supplier: s)
|
||||
@@ -523,7 +516,7 @@ describe Enterprise do
|
||||
p1 = create(:simple_product, supplier: s1)
|
||||
p2 = create(:simple_product, supplier: s2)
|
||||
|
||||
expect(Enterprise.supplying_variant_in([p1.master, p2.master])).to match_array [s1, s2]
|
||||
expect(Enterprise.supplying_variant_in([p1.variants.first, p2.variants.first])).to match_array [s1, s2]
|
||||
end
|
||||
|
||||
it "does not return duplicates" do
|
||||
@@ -531,7 +524,7 @@ describe Enterprise do
|
||||
p1 = create(:simple_product, supplier: s)
|
||||
p2 = create(:simple_product, supplier: s)
|
||||
|
||||
expect(Enterprise.supplying_variant_in([p1.master, p2.master])).to eq([s])
|
||||
expect(Enterprise.supplying_variant_in([p1.variants.first, p2.variants.first])).to eq([s])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -541,14 +534,14 @@ describe Enterprise do
|
||||
|
||||
it "returns enterprises distributing via an order cycle" do
|
||||
order_cycle = create(:simple_order_cycle, distributors: [distributor],
|
||||
variants: [product.master])
|
||||
variants: [product.variants.first])
|
||||
expect(Enterprise.distributing_products(product.id)).to eq([distributor])
|
||||
end
|
||||
|
||||
it "does not return duplicate enterprises" do
|
||||
another_product = create(:product)
|
||||
order_cycle = create(:simple_order_cycle, distributors: [distributor],
|
||||
variants: [product.master, another_product.master])
|
||||
variants: [product.variants.first, another_product.variants.first])
|
||||
expect(Enterprise.distributing_products([product.id,
|
||||
another_product.id])).to eq([distributor])
|
||||
end
|
||||
@@ -660,13 +653,13 @@ describe Enterprise do
|
||||
end
|
||||
|
||||
describe "finding variants distributed by the enterprise" do
|
||||
it "finds variants, including master, distributed by order cycle" do
|
||||
it "finds variants distributed by order cycle" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
product = create(:product)
|
||||
variant = product.variants.first
|
||||
create(:simple_order_cycle, distributors: [distributor], variants: [variant])
|
||||
|
||||
expect(distributor.distributed_variants).to match_array [product.master, variant]
|
||||
expect(distributor.distributed_variants).to match_array [variant]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -858,7 +851,7 @@ describe Enterprise do
|
||||
:simple_order_cycle,
|
||||
suppliers: [supplier],
|
||||
distributors: [distributor],
|
||||
variants: [product.master]
|
||||
variants: [product.variants.first]
|
||||
)
|
||||
expect(distributor.plus_parents_and_order_cycle_producers(order_cycle)).to eq([supplier])
|
||||
end
|
||||
@@ -872,7 +865,7 @@ describe Enterprise do
|
||||
:simple_order_cycle,
|
||||
distributors: [distributor],
|
||||
suppliers: [supplier],
|
||||
variants: [product.master]
|
||||
variants: [product.variants.first]
|
||||
)
|
||||
create(:enterprise_relationship, parent: distributor,
|
||||
child: supplier, permissions: [permission])
|
||||
@@ -890,7 +883,7 @@ describe Enterprise do
|
||||
:simple_order_cycle,
|
||||
suppliers: [supplier],
|
||||
distributors: [distributor],
|
||||
variants: [product.master]
|
||||
variants: [product.variants.first]
|
||||
)
|
||||
expected = supplier.plus_parents_and_order_cycle_producers(order_cycle)
|
||||
expect(expected).not_to include(distributor)
|
||||
@@ -908,7 +901,7 @@ permissions: [permission])
|
||||
:simple_order_cycle,
|
||||
suppliers: [sender],
|
||||
distributors: [distributor],
|
||||
variants: [product.master]
|
||||
variants: [product.variants.first]
|
||||
)
|
||||
expected = supplier.plus_parents_and_order_cycle_producers(order_cycle)
|
||||
expect(expected).to include(sender)
|
||||
|
||||
@@ -38,7 +38,7 @@ describe Exchange do
|
||||
e = create(:exchange)
|
||||
p = create(:product)
|
||||
|
||||
e.exchange_variants.create(variant: p.master)
|
||||
e.exchange_variants.create(variant: p.variants.first)
|
||||
expect(e.variants.count).to eq(1)
|
||||
end
|
||||
|
||||
@@ -243,16 +243,7 @@ describe Exchange do
|
||||
expect(Exchange.with_any_variant([v1.id, v2.id, v3.id])).to eq([ex])
|
||||
end
|
||||
|
||||
it "finds exchanges with a particular product's master variant" do
|
||||
p = create(:simple_product)
|
||||
ex = create(:exchange)
|
||||
ex.variants << p.master
|
||||
p.reload
|
||||
|
||||
expect(Exchange.with_product(p)).to eq([ex])
|
||||
end
|
||||
|
||||
it "finds exchanges with a particular product's non-master variant" do
|
||||
it "finds exchanges with a particular product's variant" do
|
||||
p = create(:simple_product)
|
||||
v = create(:variant, product: p)
|
||||
ex = create(:exchange)
|
||||
|
||||
@@ -153,10 +153,10 @@ describe OrderCycle do
|
||||
it "checks for variants" do
|
||||
p1 = create(:simple_product)
|
||||
p2 = create(:simple_product)
|
||||
oc = create(:simple_order_cycle, suppliers: [p1.supplier], variants: [p1.master])
|
||||
oc = create(:simple_order_cycle, suppliers: [p1.supplier], variants: [p1.variants.first])
|
||||
|
||||
expect(oc).to have_variant(p1.master)
|
||||
expect(oc).not_to have_variant(p2.master)
|
||||
expect(oc).to have_variant(p1.variants.first)
|
||||
expect(oc).not_to have_variant(p2.variants.first)
|
||||
end
|
||||
|
||||
describe "product exchanges" do
|
||||
@@ -193,18 +193,18 @@ describe OrderCycle do
|
||||
p1_v_deleted.deleted_at = Time.zone.now
|
||||
p1_v_deleted.save
|
||||
|
||||
e0.variants << p0.master
|
||||
e1.variants << p1.master
|
||||
e1.variants << p2.master
|
||||
e0.variants << p0.variants.first
|
||||
e1.variants << p1.variants.first
|
||||
e1.variants << p2.variants.first
|
||||
e1.variants << p2_v
|
||||
e2.variants << p1.master
|
||||
e2.variants << p1.variants.first
|
||||
e2.variants << p1_v_deleted
|
||||
e2.variants << p1_v_visible
|
||||
e2.variants << p1_v_hidden
|
||||
end
|
||||
|
||||
it "reports on the variants exchanged" do
|
||||
expect(oc.variants).to match_array [p0.master, p1.master, p2.master, p2_v, p1_v_visible,
|
||||
expect(oc.variants).to match_array [p0.variants.first, p1.variants.first, p2.variants.first, p2_v, p1_v_visible,
|
||||
p1_v_hidden]
|
||||
end
|
||||
|
||||
@@ -213,11 +213,11 @@ describe OrderCycle do
|
||||
end
|
||||
|
||||
it "reports on the variants supplied" do
|
||||
expect(oc.supplied_variants).to match_array [p0.master]
|
||||
expect(oc.supplied_variants).to match_array [p0.variants.first]
|
||||
end
|
||||
|
||||
it "reports on the variants distributed" do
|
||||
expect(oc.distributed_variants).to match_array [p1.master, p2.master, p2_v, p1_v_visible,
|
||||
expect(oc.distributed_variants).to match_array [p1.variants.first, p2.variants.first, p2_v, p1_v_visible,
|
||||
p1_v_hidden]
|
||||
end
|
||||
|
||||
@@ -236,7 +236,7 @@ describe OrderCycle do
|
||||
end
|
||||
|
||||
it "returns all variants in the outgoing exchange for the distributor provided" do
|
||||
expect(oc.variants_distributed_by(d2)).to include p1.master, p1_v_visible
|
||||
expect(oc.variants_distributed_by(d2)).to include p1.variants.first, p1_v_visible
|
||||
expect(oc.variants_distributed_by(d2)).not_to include p1_v_hidden, p1_v_deleted
|
||||
expect(oc.variants_distributed_by(d1)).to include p2_v
|
||||
end
|
||||
|
||||
@@ -232,7 +232,7 @@ describe ProductImport::ProductImporter do
|
||||
carrots = Spree::Product.find_by(name: 'Good Carrots')
|
||||
expect(carrots.supplier).to eq enterprise
|
||||
expect(carrots.on_hand).to eq 5
|
||||
expect(carrots.price).to eq 3.20
|
||||
expect(carrots.variants.first.price).to eq 3.20
|
||||
expect(carrots.variants.first.import_date).to be_within(1.minute).of Time.zone.now
|
||||
|
||||
expect(Spree::Product.find_by(name: 'Bad Potatoes')).to eq nil
|
||||
@@ -275,7 +275,7 @@ describe ProductImport::ProductImporter do
|
||||
|
||||
carrots = Spree::Product.find_by(name: 'Good Carrots')
|
||||
expect(carrots.on_hand).to eq 5
|
||||
expect(carrots.price).to eq 3.20
|
||||
expect(carrots.variants.first.price).to eq 3.20
|
||||
expect(carrots.primary_taxon.name).to eq "Vegetables"
|
||||
expect(carrots.shipping_category).to eq shipping_category
|
||||
expect(carrots.supplier).to eq enterprise
|
||||
|
||||
@@ -337,7 +337,7 @@ describe Spree::Ability do
|
||||
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy],
|
||||
for: p1)
|
||||
is_expected.to have_ability(
|
||||
[:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.master
|
||||
[:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.variants.first
|
||||
)
|
||||
end
|
||||
|
||||
@@ -346,7 +346,7 @@ describe Spree::Ability do
|
||||
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy],
|
||||
for: p_related)
|
||||
is_expected.to have_ability(
|
||||
[:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.master
|
||||
[:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.variants.first
|
||||
)
|
||||
end
|
||||
|
||||
@@ -354,7 +354,7 @@ describe Spree::Ability do
|
||||
is_expected.not_to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy],
|
||||
for: p2)
|
||||
is_expected.not_to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy],
|
||||
for: p2.master)
|
||||
for: p2.variants.first)
|
||||
end
|
||||
|
||||
it "should not be able to access admin actions on orders" do
|
||||
@@ -369,13 +369,13 @@ describe Spree::Ability do
|
||||
is_expected.to have_ability([:create], for: Spree::Variant)
|
||||
is_expected.to have_ability(
|
||||
[:admin, :index, :read, :create, :edit, :search, :update, :destroy,
|
||||
:delete], for: p1.master
|
||||
:delete], for: p1.variants.first
|
||||
)
|
||||
end
|
||||
|
||||
it "should not be able to read/write other enterprises' product variants" do
|
||||
is_expected.not_to have_ability(
|
||||
[:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p2.master
|
||||
[:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p2.variants.first
|
||||
)
|
||||
end
|
||||
|
||||
@@ -554,10 +554,10 @@ describe Spree::Ability do
|
||||
end
|
||||
|
||||
describe "variant overrides" do
|
||||
let(:vo1) { create(:variant_override, hub: d1, variant: p1.master) }
|
||||
let(:vo2) { create(:variant_override, hub: d1, variant: p2.master) }
|
||||
let(:vo3) { create(:variant_override, hub: d2, variant: p1.master) }
|
||||
let(:vo4) { create(:variant_override, hub: d2, variant: p2.master) }
|
||||
let(:vo1) { create(:variant_override, hub: d1, variant: p1.variants.first) }
|
||||
let(:vo2) { create(:variant_override, hub: d1, variant: p2.variants.first) }
|
||||
let(:vo3) { create(:variant_override, hub: d2, variant: p1.variants.first) }
|
||||
let(:vo4) { create(:variant_override, hub: d2, variant: p2.variants.first) }
|
||||
|
||||
let!(:er1) {
|
||||
create(:enterprise_relationship, parent: s1, child: d1,
|
||||
|
||||
@@ -6,7 +6,7 @@ describe Spree::Asset do
|
||||
describe "#viewable" do
|
||||
it "touches association" do
|
||||
product = create(:product)
|
||||
asset = Spree::Asset.create! { |a| a.viewable = product.master }
|
||||
asset = Spree::Asset.create! { |a| a.viewable = product }
|
||||
|
||||
product.update_column(:updated_at, 1.day.ago)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ module Spree
|
||||
subject {
|
||||
Spree::Image.create!(
|
||||
attachment: black_logo_file,
|
||||
viewable: product.master,
|
||||
viewable: product,
|
||||
)
|
||||
}
|
||||
let(:product) { create(:product) }
|
||||
|
||||
@@ -477,7 +477,7 @@ module Spree
|
||||
describe "inheriting units" do
|
||||
let!(:p) {
|
||||
create(:product, variant_unit: "weight", variant_unit_scale: 1,
|
||||
master: create(:variant, unit_value: 1000 ))
|
||||
unit_value: 1000 )
|
||||
}
|
||||
let!(:v) { p.variants.first }
|
||||
let!(:o) { create(:order) }
|
||||
|
||||
@@ -16,31 +16,20 @@ module Spree
|
||||
it 'duplicates product' do
|
||||
clone = product.duplicate
|
||||
expect(clone.name).to eq 'COPY OF ' + product.name
|
||||
expect(clone.master.sku).to eq ''
|
||||
expect(clone.image).to eq product.image
|
||||
end
|
||||
end
|
||||
|
||||
context "product has no variants" do
|
||||
context "#destroy" do
|
||||
it "should set deleted_at value" do
|
||||
product.destroy
|
||||
expect(product.deleted_at).to_not be_nil
|
||||
expect(product.master.deleted_at).to_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "product has variants" do
|
||||
before do
|
||||
create(:variant, product: product)
|
||||
product.reload.variants << create(:variant, product: product)
|
||||
end
|
||||
|
||||
context "#destroy" do
|
||||
it "should set deleted_at value" do
|
||||
product.destroy
|
||||
expect(product.deleted_at).to_not be_nil
|
||||
expect(product.variants_including_master.all? { |v| !v.deleted_at.nil? }).to be_truthy
|
||||
expect(product.variants.all? { |v| !v.deleted_at.nil? }).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -51,12 +40,6 @@ module Spree
|
||||
expect(product.variants.to_sql).to match(/ORDER BY spree_variants.position ASC/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with master variant' do
|
||||
it 'sorts variants by position' do
|
||||
expect(product.variants_including_master.to_sql).to match(/ORDER BY spree_variants.position ASC/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -241,7 +224,7 @@ module Spree
|
||||
|
||||
context "has stock movements" do
|
||||
let(:product) { create(:product) }
|
||||
let(:variant) { product.master }
|
||||
let(:variant) { product.variants.first }
|
||||
let(:stock_item) { variant.stock_items.first }
|
||||
|
||||
it "doesnt raise ReadOnlyRecord error" do
|
||||
@@ -272,14 +255,6 @@ module Spree
|
||||
expect(build(:simple_product, supplier: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it "does not save when master is invalid" do
|
||||
product = build(:product)
|
||||
product.variant_unit = 'weight'
|
||||
product.master.unit_value = nil
|
||||
|
||||
expect(product.save).to eq(false)
|
||||
end
|
||||
|
||||
it "defaults available_on to now" do
|
||||
Timecop.freeze do
|
||||
product = Product.new
|
||||
@@ -371,17 +346,11 @@ module Spree
|
||||
product.save!
|
||||
end
|
||||
|
||||
it "copies the properties on master variant to the first standard variant" do
|
||||
it "copies properties to the first standard variant" do
|
||||
expect(product.variants.reload.length).to eq 1
|
||||
standard_variant = product.variants.reload.first
|
||||
expect(standard_variant.price).to eq 4.27
|
||||
end
|
||||
|
||||
it "only duplicates master with after_save when no standard variants exist" do
|
||||
expect(product).to receive :ensure_standard_variant
|
||||
product.name = "Something else"
|
||||
expect{ product.save! }.to_not change{ product.variants.count }
|
||||
end
|
||||
end
|
||||
|
||||
context "when the unit is items" do
|
||||
@@ -525,8 +494,8 @@ module Spree
|
||||
d2 = create(:distributor_enterprise)
|
||||
p1 = create(:product)
|
||||
p2 = create(:product)
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d1], variants: [p1.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d2], variants: [p2.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d1], variants: [p1.variants.first])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d2], variants: [p2.variants.first])
|
||||
expect(Product.in_distributor(d1)).to eq([p1])
|
||||
end
|
||||
|
||||
@@ -550,7 +519,7 @@ module Spree
|
||||
p = create(:product)
|
||||
oc = create(:simple_order_cycle, coordinator: c, suppliers: [s], distributors: [d])
|
||||
ex = oc.exchanges.incoming.first
|
||||
ex.variants << p.master
|
||||
ex.variants << p.variants.first
|
||||
|
||||
expect(Product.in_distributor(d)).to be_empty
|
||||
end
|
||||
@@ -602,8 +571,8 @@ module Spree
|
||||
d2 = create(:distributor_enterprise)
|
||||
p1 = create(:product)
|
||||
p2 = create(:product)
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d1], variants: [p1.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d2], variants: [p2.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d1], variants: [p1.variants.first])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d2], variants: [p2.variants.first])
|
||||
expect(Product.in_supplier_or_distributor(d1)).to eq([p1])
|
||||
end
|
||||
|
||||
@@ -611,7 +580,7 @@ module Spree
|
||||
s = create(:supplier_enterprise)
|
||||
d = create(:distributor_enterprise)
|
||||
p = create(:product, supplier: s)
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.master])
|
||||
create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.variants.first])
|
||||
[s, d].each { |e| expect(Product.in_supplier_or_distributor(e)).to eq([p]) }
|
||||
end
|
||||
end
|
||||
@@ -624,9 +593,9 @@ module Spree
|
||||
p1 = create(:product)
|
||||
p2 = create(:product)
|
||||
oc1 = create(:simple_order_cycle, suppliers: [s], distributors: [d1],
|
||||
variants: [p1.master])
|
||||
variants: [p1.variants.first])
|
||||
oc2 = create(:simple_order_cycle, suppliers: [s], distributors: [d2],
|
||||
variants: [p2.master])
|
||||
variants: [p2.variants.first])
|
||||
expect(Product.in_order_cycle(oc1)).to eq([p1])
|
||||
end
|
||||
end
|
||||
@@ -640,9 +609,9 @@ module Spree
|
||||
p2 = create(:product)
|
||||
p3 = create(:product)
|
||||
oc2 = create(:simple_order_cycle, suppliers: [s], distributors: [d2],
|
||||
variants: [p2.master], orders_open_at: 8.days.ago, orders_close_at: 1.day.ago)
|
||||
variants: [p2.variants.first], orders_open_at: 8.days.ago, orders_close_at: 1.day.ago)
|
||||
oc2 = create(:simple_order_cycle, suppliers: [s], distributors: [d3],
|
||||
variants: [p3.master], orders_close_at: Date.tomorrow)
|
||||
variants: [p3.variants.first], orders_close_at: Date.tomorrow)
|
||||
expect(Product.in_an_active_order_cycle).to eq([p3])
|
||||
end
|
||||
end
|
||||
@@ -820,8 +789,8 @@ module Spree
|
||||
d2 = create(:distributor_enterprise)
|
||||
p1 = create(:product)
|
||||
p2 = create(:product)
|
||||
oc1 = create(:simple_order_cycle, distributors: [d1], variants: [p1.master])
|
||||
oc2 = create(:simple_order_cycle, distributors: [d2], variants: [p2.master])
|
||||
oc1 = create(:simple_order_cycle, distributors: [d1], variants: [p1.variants.first])
|
||||
oc2 = create(:simple_order_cycle, distributors: [d2], variants: [p2.variants.first])
|
||||
|
||||
expect(p1).to be_in_distributor d1
|
||||
expect(p1).not_to be_in_distributor d2
|
||||
@@ -832,8 +801,8 @@ module Spree
|
||||
d2 = create(:distributor_enterprise)
|
||||
p1 = create(:product)
|
||||
p2 = create(:product)
|
||||
oc1 = create(:simple_order_cycle, distributors: [d1], variants: [p1.master])
|
||||
oc2 = create(:simple_order_cycle, distributors: [d2], variants: [p2.master])
|
||||
oc1 = create(:simple_order_cycle, distributors: [d1], variants: [p1.variants.first])
|
||||
oc2 = create(:simple_order_cycle, distributors: [d2], variants: [p2.variants.first])
|
||||
|
||||
expect(p1).to be_in_order_cycle oc1
|
||||
expect(p1).not_to be_in_order_cycle oc2
|
||||
@@ -859,18 +828,6 @@ module Spree
|
||||
|
||||
expect(v.reload.unit_presentation).to eq "1L"
|
||||
end
|
||||
|
||||
it "updates its master variant's unit values" do
|
||||
p.master.update!(unit_value: 1)
|
||||
p.reload
|
||||
|
||||
expect(p.master.unit_presentation).to eq "1g"
|
||||
|
||||
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
|
||||
p.reload
|
||||
|
||||
expect(p.master.unit_presentation).to eq "1L"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -893,13 +850,7 @@ module Spree
|
||||
create(:exchange, order_cycle: oc, incoming: true, sender: s, receiver: oc.coordinator)
|
||||
}
|
||||
|
||||
it "removes the master variant from all order cycles" do
|
||||
e.variants << p.master
|
||||
p.destroy
|
||||
expect(e.variants.reload).to be_empty
|
||||
end
|
||||
|
||||
it "removes all other variants from order cycles" do
|
||||
it "removes all variants from order cycles" do
|
||||
e.variants << v
|
||||
p.destroy
|
||||
expect(e.variants.reload).to be_empty
|
||||
|
||||
@@ -232,16 +232,16 @@ describe Spree::Variant do
|
||||
let!(:d2) { create(:distributor_enterprise) }
|
||||
let!(:p1) { create(:simple_product) }
|
||||
let!(:p2) { create(:simple_product) }
|
||||
let!(:oc1) { create(:simple_order_cycle, distributors: [d1], variants: [p1.master]) }
|
||||
let!(:oc2) { create(:simple_order_cycle, distributors: [d2], variants: [p2.master]) }
|
||||
let!(:oc1) { create(:simple_order_cycle, distributors: [d1], variants: [p1.variants.first]) }
|
||||
let!(:oc2) { create(:simple_order_cycle, distributors: [d2], variants: [p2.variants.first]) }
|
||||
|
||||
it "shows variants in an order cycle distribution" do
|
||||
expect(Spree::Variant.in_distributor(d1)).to eq([p1.master])
|
||||
expect(Spree::Variant.in_distributor(d1)).to eq([p1.variants.first])
|
||||
end
|
||||
|
||||
it "doesn't show duplicates" do
|
||||
oc_dup = create(:simple_order_cycle, distributors: [d1], variants: [p1.master])
|
||||
expect(Spree::Variant.in_distributor(d1)).to eq([p1.master])
|
||||
oc_dup = create(:simple_order_cycle, distributors: [d1], variants: [p1.variants.first])
|
||||
expect(Spree::Variant.in_distributor(d1)).to eq([p1.variants.first])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -250,18 +250,18 @@ describe Spree::Variant do
|
||||
let!(:d2) { create(:distributor_enterprise) }
|
||||
let!(:p1) { create(:product) }
|
||||
let!(:p2) { create(:product) }
|
||||
let!(:oc1) { create(:simple_order_cycle, distributors: [d1], variants: [p1.master]) }
|
||||
let!(:oc2) { create(:simple_order_cycle, distributors: [d2], variants: [p2.master]) }
|
||||
let!(:oc1) { create(:simple_order_cycle, distributors: [d1], variants: [p1.variants.first]) }
|
||||
let!(:oc2) { create(:simple_order_cycle, distributors: [d2], variants: [p2.variants.first]) }
|
||||
|
||||
it "shows variants in an order cycle" do
|
||||
expect(Spree::Variant.in_order_cycle(oc1)).to eq([p1.master])
|
||||
expect(Spree::Variant.in_order_cycle(oc1)).to eq([p1.variants.first])
|
||||
end
|
||||
|
||||
it "doesn't show duplicates" do
|
||||
ex = create(:exchange, order_cycle: oc1, sender: oc1.coordinator, receiver: d2)
|
||||
ex.variants << p1.master
|
||||
ex.variants << p1.variants.first
|
||||
|
||||
expect(Spree::Variant.in_order_cycle(oc1)).to eq([p1.master])
|
||||
expect(Spree::Variant.in_order_cycle(oc1)).to eq([p1.variants.first])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -520,10 +520,6 @@ describe Spree::Variant do
|
||||
variant.unit_value = nil
|
||||
expect(variant).not_to be_valid
|
||||
end
|
||||
|
||||
it "has a valid master variant" do
|
||||
expect(product.master).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -552,10 +548,6 @@ describe Spree::Variant do
|
||||
expect(variant).to be_valid
|
||||
expect(variant.unit_value).to eq 1.0
|
||||
end
|
||||
|
||||
it "has a valid master variant" do
|
||||
expect(product.master).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "when the product's unit is non-weight" do
|
||||
|
||||
@@ -228,9 +228,9 @@ describe '
|
||||
end
|
||||
|
||||
context "creating new variants" do
|
||||
let!(:product) { create(:product, variant_unit: 'weight', variant_unit_scale: 1000) }
|
||||
|
||||
before do
|
||||
# Given a product without variants or a unit
|
||||
p = FactoryBot.create(:product, variant_unit: 'weight', variant_unit_scale: 1000)
|
||||
login_as_admin
|
||||
visit spree.admin_products_path
|
||||
|
||||
@@ -278,18 +278,19 @@ describe '
|
||||
end
|
||||
|
||||
context "handle the 'on_demand' variant case creation" do
|
||||
let(:v1) { create(:variant, product: product, on_hand: 4) }
|
||||
let(:v2) { create(:variant, product: product, on_demand: true) }
|
||||
|
||||
before do
|
||||
p = Spree::Product.first
|
||||
p.master.update_attribute(:on_hand, 5)
|
||||
p.save
|
||||
v1 = FactoryBot.create(:variant, product: p, is_master: false, on_hand: 4)
|
||||
v2 = FactoryBot.create(:variant, product: p, is_master: false, on_demand: true)
|
||||
p.variants << v1
|
||||
p.variants << v2
|
||||
product.variants << v1
|
||||
product.variants << v2
|
||||
|
||||
visit spree.admin_products_path
|
||||
page.find('a.view-variants').click
|
||||
end
|
||||
|
||||
it "when variant unit value is: '120'" do
|
||||
within "tr#v_#{Spree::Variant.second.id}" do
|
||||
within "tr#v_#{v2.id}" do
|
||||
page.find(".add-variant").click
|
||||
end
|
||||
|
||||
@@ -303,7 +304,7 @@ describe '
|
||||
end
|
||||
|
||||
it "creating a variant with unit value is: '120g' and 'on_hand' filled" do
|
||||
within "tr#v_#{Spree::Variant.second.id}" do
|
||||
within "tr#v_#{v2.id}" do
|
||||
page.find(".add-variant").click
|
||||
end
|
||||
|
||||
@@ -318,7 +319,7 @@ describe '
|
||||
end
|
||||
|
||||
it "creating a variant with unit value is: '120g' and 'on_demand' checked" do
|
||||
within "tr#v_#{Spree::Variant.second.id}" do
|
||||
within "tr#v_#{v2.id}" do
|
||||
page.find(".add-variant").trigger("click")
|
||||
end
|
||||
|
||||
|
||||
@@ -561,8 +561,8 @@ describe '
|
||||
it "loading edit product image page including url filter" do
|
||||
product = create(:simple_product, supplier: @supplier2)
|
||||
image = white_logo_file
|
||||
image_object = Spree::Image.create(viewable_id: product.master.id,
|
||||
viewable_type: 'Spree::Variant', alt: "position 1",
|
||||
image_object = Spree::Image.create(viewable_id: product.id,
|
||||
viewable_type: 'Spree::Product', alt: "position 1",
|
||||
attachment: image, position: 1)
|
||||
|
||||
visit spree.admin_product_images_path(product, filter)
|
||||
@@ -582,8 +582,8 @@ describe '
|
||||
it "updating a product image including url filter" do
|
||||
product = create(:simple_product, supplier: @supplier2)
|
||||
image = white_logo_file
|
||||
image_object = Spree::Image.create(viewable_id: product.master.id,
|
||||
viewable_type: 'Spree::Variant', alt: "position 1",
|
||||
image_object = Spree::Image.create(viewable_id: product.id,
|
||||
viewable_type: 'Spree::Product', alt: "position 1",
|
||||
attachment: image, position: 1)
|
||||
|
||||
file_path = Rails.root + "spec/support/fixtures/thinking-cat.jpg"
|
||||
@@ -604,7 +604,7 @@ describe '
|
||||
product = create(:simple_product, supplier: @supplier2)
|
||||
|
||||
image = white_logo_file
|
||||
Spree::Image.create(viewable_id: product.master.id, viewable_type: 'Spree::Variant',
|
||||
Spree::Image.create(viewable_id: product.id, viewable_type: 'Spree::Product',
|
||||
alt: "position 1", attachment: image, position: 1)
|
||||
|
||||
visit spree.admin_product_images_path(product)
|
||||
@@ -619,7 +619,7 @@ describe '
|
||||
it "deleting product images" do
|
||||
product = create(:simple_product, supplier: @supplier2)
|
||||
image = white_logo_file
|
||||
Spree::Image.create(viewable_id: product.master.id, viewable_type: 'Spree::Variant',
|
||||
Spree::Image.create(viewable_id: product.id, viewable_type: 'Spree::Product',
|
||||
alt: "position 1", attachment: image, position: 1)
|
||||
|
||||
visit spree.admin_product_images_path(product)
|
||||
@@ -637,7 +637,7 @@ describe '
|
||||
it "deleting product image including url filter" do
|
||||
product = create(:simple_product, supplier: @supplier2)
|
||||
image = white_logo_file
|
||||
Spree::Image.create(viewable_id: product.master.id, viewable_type: 'Spree::Variant',
|
||||
Spree::Image.create(viewable_id: product.id, viewable_type: 'Spree::Product',
|
||||
alt: "position 1", attachment: image, position: 1)
|
||||
|
||||
visit spree.admin_product_images_path(product, filter)
|
||||
|
||||
@@ -45,7 +45,7 @@ describe "Packing Reports" do
|
||||
|
||||
create(:line_item_with_shipment, variant: variant1, quantity: 1, order: order1)
|
||||
create(:line_item_with_shipment, variant: variant2, quantity: 3, order: order1)
|
||||
create(:line_item_with_shipment, variant: product2.master, quantity: 3, order: order2)
|
||||
create(:line_item_with_shipment, variant: product2.variants.first, quantity: 3, order: order2)
|
||||
end
|
||||
|
||||
describe "Pack By Customer" do
|
||||
|
||||
@@ -568,7 +568,7 @@ describe '
|
||||
let(:order_cycle) {
|
||||
create(:simple_order_cycle, coordinator: distributor1,
|
||||
coordinator_fees: [enterprise_fee1, enterprise_fee2],
|
||||
distributors: [distributor1], variants: [product1.master])
|
||||
distributors: [distributor1], variants: [product1.variants.first])
|
||||
}
|
||||
|
||||
let!(:zone) { create(:zone_with_member) }
|
||||
|
||||
Reference in New Issue
Block a user