mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-09 03:20:21 +00:00
Merge pull request #13087 from mkllnk/stock-location
Remove class Spree::StockLocation
This commit is contained in:
@@ -339,7 +339,6 @@ Naming/VariableNumber:
|
||||
- 'app/models/preference_sections/main_links_section.rb'
|
||||
- 'lib/spree/core/controller_helpers/common.rb'
|
||||
- 'spec/controllers/spree/admin/search_controller_spec.rb'
|
||||
- 'spec/factories/stock_location_factory.rb'
|
||||
- 'spec/models/spree/stock_item_spec.rb'
|
||||
- 'spec/models/spree/tax_rate_spec.rb'
|
||||
- 'spec/requests/api/orders_spec.rb'
|
||||
|
||||
@@ -187,18 +187,17 @@ addVariantFromStockLocation = function() {
|
||||
$('#stock_details').hide();
|
||||
|
||||
var variant_id = $('input.variant_autocomplete').val();
|
||||
var stock_location_id = $(this).data('stock-location-id');
|
||||
var quantity = $("input.quantity[data-stock-location-id='" + stock_location_id + "']").val();
|
||||
var quantity = $("input.quantity").val();
|
||||
|
||||
var shipment = _.find(shipments, function(shipment){
|
||||
return shipment.stock_location_id == stock_location_id && (shipment.state == 'ready' || shipment.state == 'pending');
|
||||
return shipment.state == 'ready' || shipment.state == 'pending';
|
||||
});
|
||||
|
||||
if(shipment==undefined){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: Spree.url(Spree.routes.orders_api + "/" + order_number + "/shipments.json"),
|
||||
data: { variant_id: variant_id, quantity: quantity, stock_location_id: stock_location_id }
|
||||
data: { variant_id: variant_id, quantity: quantity }
|
||||
}).done(function( msg ) {
|
||||
window.location.reload();
|
||||
}).error(function( msg ) {
|
||||
|
||||
@@ -14,7 +14,7 @@ module Api
|
||||
def create
|
||||
variant = scoped_variant(params[:variant_id])
|
||||
quantity = params[:quantity].to_i
|
||||
@shipment = get_or_create_shipment(params[:stock_location_id])
|
||||
@shipment = @order.shipment || @order.shipments.create
|
||||
|
||||
@order.contents.add(variant, quantity, @shipment)
|
||||
|
||||
@@ -116,10 +116,6 @@ module Api
|
||||
variant
|
||||
end
|
||||
|
||||
def get_or_create_shipment(stock_location_id)
|
||||
@order.shipment || @order.shipments.create(stock_location_id:)
|
||||
end
|
||||
|
||||
def shipment_params
|
||||
return {} unless params.has_key? :shipment
|
||||
|
||||
|
||||
@@ -78,11 +78,6 @@ module VariantStock
|
||||
on_demand || total_on_hand >= quantity
|
||||
end
|
||||
|
||||
# Moving Spree::StockLocation.fill_status to the variant enables us
|
||||
# to override this behaviour for variant overrides
|
||||
# We can have this responsibility here in the variant because there is
|
||||
# only one stock item per variant
|
||||
#
|
||||
# Here we depend only on variant.total_on_hand and variant.on_demand.
|
||||
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
|
||||
def fill_status(quantity)
|
||||
@@ -107,13 +102,15 @@ module VariantStock
|
||||
raise_error_if_no_stock_item_available
|
||||
|
||||
# Creates a stock movement: it updates stock_item.count_on_hand and fills backorders
|
||||
#
|
||||
# This is the original Spree::StockLocation#move,
|
||||
# except that we raise an error if the stock item is missing,
|
||||
# because, unlike Spree, we should always have exactly one stock item per variant.
|
||||
stock_item.stock_movements.create!(quantity:, originator:)
|
||||
end
|
||||
|
||||
# There shouldn't be any other stock items, because we should
|
||||
# have only one stock location.
|
||||
def stock_item
|
||||
stock_items.first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Persists the single stock item associated to this variant. As defined in
|
||||
@@ -139,10 +136,4 @@ module VariantStock
|
||||
def overwrite_stock_levels(new_level)
|
||||
stock_item.adjust_count_on_hand(new_level.to_i - stock_item.count_on_hand)
|
||||
end
|
||||
|
||||
# There shouldn't be any other stock items, because we should
|
||||
# have only one stock location.
|
||||
def stock_item
|
||||
stock_items.first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,18 +35,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
# This was refactored from a simpler query because the previous implementation
|
||||
# lead to issues once users tried to modify the objects returned. That's due
|
||||
# to ActiveRecord `joins(shipment: :stock_location)` only return readonly
|
||||
# objects
|
||||
#
|
||||
# Returns an array of backordered inventory units as per a given stock item
|
||||
def self.backordered_for_stock_item(stock_item)
|
||||
backordered_per_variant(stock_item).select do |unit|
|
||||
unit.shipment.stock_location == stock_item.stock_location
|
||||
end
|
||||
end
|
||||
|
||||
def self.finalize_units!(inventory_units)
|
||||
inventory_units.map do |iu|
|
||||
iu.update_columns(
|
||||
@@ -57,8 +45,7 @@ module Spree
|
||||
end
|
||||
|
||||
def find_stock_item
|
||||
Spree::StockItem.find_by(stock_location_id: shipment.stock_location_id,
|
||||
variant_id:)
|
||||
Spree::StockItem.find_by(variant_id:)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -12,8 +12,8 @@ module Spree
|
||||
# have inventory assigned via +order.create_proposed_shipment+) or when
|
||||
# shipment is explicitly passed
|
||||
#
|
||||
# In case shipment is passed the stock location should only unstock or
|
||||
# restock items if the order is completed. That is so because stock items
|
||||
# In case shipment is passed stock should only be adjusted
|
||||
# if the order is completed. That is so because stock items
|
||||
# are always unstocked when the order is completed through +shipment.finalize+
|
||||
def verify(line_item, shipment = nil)
|
||||
if order.completed? || shipment.present?
|
||||
@@ -60,27 +60,24 @@ module Spree
|
||||
# Returns either one of the shipment:
|
||||
#
|
||||
# first unshipped that already includes this variant
|
||||
# first unshipped that's leaving from a stock_location that stocks this variant
|
||||
def determine_target_shipment(variant)
|
||||
target_shipment = order.shipments.detect do |shipment|
|
||||
(shipment.ready? || shipment.pending?) && shipment.contains?(variant)
|
||||
end
|
||||
|
||||
target_shipment || order.shipments.detect do |shipment|
|
||||
(shipment.ready? || shipment.pending?) &&
|
||||
variant.stock_location_ids.include?(shipment.stock_location_id)
|
||||
shipment.ready? || shipment.pending?
|
||||
end
|
||||
end
|
||||
|
||||
def add_to_shipment(shipment, variant, quantity)
|
||||
on_hand, back_order = shipment.stock_location.fill_status(variant, quantity)
|
||||
on_hand, back_order = variant.fill_status(quantity)
|
||||
|
||||
on_hand.times { shipment.set_up_inventory('on_hand', variant, order) }
|
||||
back_order.times { shipment.set_up_inventory('backordered', variant, order) }
|
||||
|
||||
# adding to this shipment, and removing from stock_location
|
||||
if order.completed?
|
||||
shipment.stock_location.unstock(variant, quantity, shipment)
|
||||
variant.move(-quantity, shipment)
|
||||
end
|
||||
|
||||
quantity
|
||||
@@ -103,9 +100,8 @@ module Spree
|
||||
end
|
||||
shipment.destroy if shipment.inventory_units.reload.count == 0
|
||||
|
||||
# removing this from shipment, and adding to stock_location
|
||||
if order.completed? && restock_item
|
||||
shipment.stock_location.restock variant, removed_quantity, shipment
|
||||
variant.move(removed_quantity, shipment)
|
||||
end
|
||||
|
||||
removed_quantity
|
||||
|
||||
@@ -5,10 +5,10 @@ require 'ostruct'
|
||||
module Spree
|
||||
class Shipment < ApplicationRecord
|
||||
self.belongs_to_required_by_default = false
|
||||
self.ignored_columns += [:stock_location_id]
|
||||
|
||||
belongs_to :order, class_name: 'Spree::Order'
|
||||
belongs_to :address, class_name: 'Spree::Address'
|
||||
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
||||
|
||||
has_many :shipping_rates, dependent: :delete_all
|
||||
has_many :shipping_methods, through: :shipping_rates
|
||||
@@ -257,7 +257,7 @@ module Spree
|
||||
end
|
||||
|
||||
def to_package
|
||||
package = OrderManagement::Stock::Package.new(stock_location, order)
|
||||
package = OrderManagement::Stock::Package.new(order)
|
||||
grouped_inventory_units = inventory_units.includes(:variant).group_by do |iu|
|
||||
[iu.variant, iu.state_name]
|
||||
end
|
||||
@@ -313,11 +313,11 @@ module Spree
|
||||
end
|
||||
|
||||
def manifest_unstock(item)
|
||||
stock_location.unstock item.variant, item.quantity, self
|
||||
item.variant.move(-1 * item.quantity, self)
|
||||
end
|
||||
|
||||
def manifest_restock(item)
|
||||
stock_location.restock item.variant, item.quantity, self
|
||||
item.variant.move(item.quantity, self)
|
||||
end
|
||||
|
||||
def generate_shipment_number
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
|
||||
module Spree
|
||||
class StockItem < ApplicationRecord
|
||||
self.ignored_columns += [:stock_location_id]
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
belongs_to :stock_location, class_name: 'Spree::StockLocation', inverse_of: :stock_items
|
||||
belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant'
|
||||
has_many :stock_movements, dependent: :destroy
|
||||
|
||||
validates :variant_id, uniqueness: { scope: [:stock_location_id, :deleted_at] }
|
||||
validates :variant_id, uniqueness: { scope: [:deleted_at] }
|
||||
validates :count_on_hand, numericality: { greater_than_or_equal_to: 0, unless: :backorderable? }
|
||||
|
||||
delegate :weight, to: :variant
|
||||
delegate :name, to: :variant, prefix: true
|
||||
|
||||
def backordered_inventory_units
|
||||
Spree::InventoryUnit.backordered_for_stock_item(self)
|
||||
Spree::InventoryUnit.backordered_per_variant(self)
|
||||
end
|
||||
|
||||
def adjust_count_on_hand(value)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
class StockLocation < ApplicationRecord
|
||||
self.belongs_to_required_by_default = false
|
||||
self.ignored_columns += [:backorderable_default, :active]
|
||||
|
||||
has_many :stock_items, dependent: :delete_all, inverse_of: :stock_location
|
||||
has_many :stock_movements, through: :stock_items
|
||||
|
||||
belongs_to :state, class_name: 'Spree::State'
|
||||
belongs_to :country, class_name: 'Spree::Country'
|
||||
|
||||
validates :name, presence: true
|
||||
|
||||
after_create :create_stock_items
|
||||
|
||||
# Wrapper for creating a new stock item respecting the backorderable config
|
||||
def stock_item(variant)
|
||||
stock_items.where(variant_id: variant).order(:id).first
|
||||
end
|
||||
|
||||
def stock_item_or_create(variant)
|
||||
stock_item(variant) || stock_items.create(variant:)
|
||||
end
|
||||
|
||||
def count_on_hand(variant)
|
||||
stock_item(variant).try(:count_on_hand)
|
||||
end
|
||||
|
||||
def backorderable?(variant)
|
||||
stock_item(variant).try(:backorderable?)
|
||||
end
|
||||
|
||||
def restock(variant, quantity, originator = nil)
|
||||
move(variant, quantity, originator)
|
||||
end
|
||||
|
||||
def unstock(variant, quantity, originator = nil)
|
||||
move(variant, -quantity, originator)
|
||||
end
|
||||
|
||||
def move(variant, quantity, originator = nil)
|
||||
variant.move(quantity, originator)
|
||||
end
|
||||
|
||||
def fill_status(variant, quantity)
|
||||
variant.fill_status(quantity)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_stock_items
|
||||
Variant.find_each { |variant| stock_items.create!(variant:) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -39,7 +39,6 @@ module Spree
|
||||
has_many :line_items, inverse_of: :variant, dependent: nil
|
||||
|
||||
has_many :stock_items, dependent: :destroy, inverse_of: :variant
|
||||
has_many :stock_locations, through: :stock_items
|
||||
has_many :images, -> { order(:position) }, as: :viewable,
|
||||
dependent: :destroy,
|
||||
class_name: "Spree::Image"
|
||||
@@ -268,9 +267,7 @@ module Spree
|
||||
def create_stock_items
|
||||
return unless stock_items.empty?
|
||||
|
||||
StockLocation.find_each do |stock_location|
|
||||
stock_items.create!(stock_location:)
|
||||
end
|
||||
stock_items.create!
|
||||
end
|
||||
|
||||
def update_weight_from_unit_value
|
||||
|
||||
@@ -61,7 +61,7 @@ class ProductScopeQuery
|
||||
def product_query_includes
|
||||
[
|
||||
image: { attachment_attachment: :blob },
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides]
|
||||
variants: [:default_price, :stock_items, :variant_overrides]
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ module Api
|
||||
object.variants,
|
||||
each_serializer: Api::Admin::VariantSerializer,
|
||||
image: thumb_url,
|
||||
stock_location: Spree::StockLocation.first
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ module Api
|
||||
attributes :id, :name, :producer_name, :image, :sku, :import_date, :tax_category_id,
|
||||
:options_text, :unit_value, :unit_description, :unit_to_display,
|
||||
:display_as, :display_name, :name_to_display, :variant_overrides_count,
|
||||
:price, :on_demand, :on_hand, :in_stock, :stock_location_id, :stock_location_name,
|
||||
:price, :on_demand, :on_hand, :in_stock,
|
||||
:variant_unit, :variant_unit_scale, :variant_unit_name, :variant_unit_with_scale
|
||||
|
||||
has_one :primary_taxon, key: :category_id, embed: :id
|
||||
@@ -44,18 +44,6 @@ module Api
|
||||
object.in_stock?
|
||||
end
|
||||
|
||||
def stock_location_id
|
||||
return if object.stock_items.empty?
|
||||
|
||||
options[:stock_location]&.id || object.stock_items.first.stock_location.id
|
||||
end
|
||||
|
||||
def stock_location_name
|
||||
return if object.stock_items.empty?
|
||||
|
||||
options[:stock_location]&.name || object.stock_items.first.stock_location.name
|
||||
end
|
||||
|
||||
def variant_overrides_count
|
||||
object.variant_overrides.count
|
||||
end
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
|
||||
module Api
|
||||
class ShipmentSerializer < ActiveModel::Serializer
|
||||
attributes :id, :tracking, :number, :order_id, :cost, :shipped_at, :stock_location_name, :state
|
||||
attributes :id, :tracking, :number, :order_id, :cost, :shipped_at, :state
|
||||
|
||||
def order_id
|
||||
object.order.number
|
||||
end
|
||||
|
||||
def stock_location_name
|
||||
object.stock_location.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Encapsulates the concept of default stock location that OFN has, as explained
|
||||
# in https://github.com/openfoodfoundation/openfoodnetwork/wiki/Spree-Upgrade%3A-Stock-locations
|
||||
class DefaultStockLocation
|
||||
NAME = 'default'
|
||||
|
||||
def self.find_or_create
|
||||
Spree::StockLocation.find_or_create_by(name: NAME)
|
||||
end
|
||||
end
|
||||
@@ -117,7 +117,7 @@ class ProductsRenderer
|
||||
|
||||
# rubocop:disable Rails/FindEach # .each returns an array, .find_each returns nil
|
||||
distributed_products.variants_relation.
|
||||
includes(:default_price, :stock_locations, :product).
|
||||
includes(:default_price, :product).
|
||||
where(product_id: products).
|
||||
each { |v| scoper.scope(v) } # Scope results with variant_overrides
|
||||
# rubocop:enable Rails/FindEach
|
||||
|
||||
@@ -30,5 +30,5 @@
|
||||
var order_number = '#{@order.number}';
|
||||
var shipments = [];
|
||||
- @order.shipments.each do |shipment|
|
||||
shipments.push(#{shipment.to_json(:root => false, :include => [:inventory_units, :stock_location]).html_safe});
|
||||
shipments.push(#{shipment.to_json(:root => false, :include => [:inventory_units]).html_safe});
|
||||
= render :partial => 'spree/admin/shared/update_order_state', :handlers => [:erb], :formats => [:js]
|
||||
|
||||
@@ -51,10 +51,10 @@
|
||||
</td>
|
||||
{{/if}}
|
||||
<td>
|
||||
<input class="quantity" id="stock_item_quantity" data-stock-location-id="{{variant.stock_location_id}}" type="number" min="1" value="1">
|
||||
<input class="quantity" id="stock_item_quantity" type="number" min="1" value="1">
|
||||
</td>
|
||||
<td class="actions">
|
||||
<button class="add_variant no-text icon-plus icon_link with-tip" data-stock-location-id="{{variant.stock_location_id}}" title="Add" data-action="add"></button>
|
||||
<button class="add_variant no-text icon-plus icon_link with-tip" title="Add" data-action="add"></button>
|
||||
</td>
|
||||
{{else}}
|
||||
<td><%= t('.out_of_stock') %></td>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
class SetDefaultStockLocationOnShipments < ActiveRecord::Migration[4.2]
|
||||
class SpreeStockLocation < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def up
|
||||
if Spree::Shipment.where('stock_location_id IS NULL').count > 0
|
||||
location = DefaultStockLocation.find_or_create
|
||||
location = SpreeStockLocation.find_or_create_by(name: "default")
|
||||
Spree::Shipment.where('stock_location_id IS NULL').update_all(stock_location_id: location.id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AllowNullStockLocationIdOnSpreeStockItems < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
change_column_null :spree_stock_items, :stock_location_id, true
|
||||
end
|
||||
end
|
||||
@@ -822,7 +822,7 @@ ActiveRecord::Schema[7.0].define(version: 2025_01_13_055412) do
|
||||
end
|
||||
|
||||
create_table "spree_stock_items", id: :serial, force: :cascade do |t|
|
||||
t.integer "stock_location_id", null: false
|
||||
t.integer "stock_location_id"
|
||||
t.integer "variant_id", null: false
|
||||
t.integer "count_on_hand", default: 0, null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
|
||||
@@ -30,5 +30,4 @@ require File.join(File.dirname(__FILE__), 'default', 'zones')
|
||||
Rails.logger.info "[db:seed] Seeding Users"
|
||||
require File.join(File.dirname(__FILE__), 'default', 'users')
|
||||
|
||||
DefaultStockLocation.find_or_create
|
||||
DefaultShippingCategory.find_or_create
|
||||
|
||||
@@ -8,7 +8,6 @@ class CatalogItemBuilder < DfcBuilder
|
||||
|
||||
if variant.stock_items.empty?
|
||||
variant.stock_items << Spree::StockItem.new(
|
||||
stock_location: DefaultStockLocation.find_or_create,
|
||||
variant:,
|
||||
)
|
||||
end
|
||||
|
||||
@@ -222,9 +222,6 @@ RSpec.describe SuppliedProductBuilder do
|
||||
}
|
||||
|
||||
it "creates a new Spree::Product and variant" do
|
||||
# We need this to save stock:
|
||||
DefaultStockLocation.find_or_create
|
||||
|
||||
create(:taxon)
|
||||
|
||||
expect(imported_variant).to be_a(Spree::Variant)
|
||||
|
||||
@@ -41,8 +41,7 @@ module OrderManagement
|
||||
end
|
||||
|
||||
def build_packer(order)
|
||||
stock_location = DefaultStockLocation.find_or_create
|
||||
OrderManagement::Stock::Packer.new(stock_location, order)
|
||||
OrderManagement::Stock::Packer.new(order)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,11 +5,10 @@ module OrderManagement
|
||||
class Package
|
||||
ContentItem = Struct.new(:variant, :quantity, :state)
|
||||
|
||||
attr_reader :stock_location, :order, :contents
|
||||
attr_reader :order, :contents
|
||||
attr_accessor :shipping_rates
|
||||
|
||||
def initialize(stock_location, order, contents = [])
|
||||
@stock_location = stock_location
|
||||
def initialize(order, contents = [])
|
||||
@order = order
|
||||
@contents = contents
|
||||
@shipping_rates = []
|
||||
@@ -94,7 +93,6 @@ module OrderManagement
|
||||
def to_shipment
|
||||
shipment = Spree::Shipment.new
|
||||
shipment.order = order
|
||||
shipment.stock_location = stock_location
|
||||
shipment.shipping_rates = shipping_rates
|
||||
|
||||
contents.each do |item|
|
||||
|
||||
@@ -3,22 +3,21 @@
|
||||
module OrderManagement
|
||||
module Stock
|
||||
class Packer
|
||||
attr_reader :stock_location, :order
|
||||
attr_reader :order
|
||||
|
||||
def initialize(stock_location, order)
|
||||
@stock_location = stock_location
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def package
|
||||
package = OrderManagement::Stock::Package.new(stock_location, order)
|
||||
package = OrderManagement::Stock::Package.new(order)
|
||||
order.line_items.each do |line_item|
|
||||
next unless stock_location.stock_item(line_item.variant)
|
||||
|
||||
variant = line_item.variant
|
||||
next unless variant.stock_item
|
||||
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(order.distributor).scope(variant)
|
||||
|
||||
on_hand, backordered = stock_location.fill_status(variant, line_item.quantity)
|
||||
on_hand, backordered = variant.fill_status(line_item.quantity)
|
||||
package.add variant, on_hand, :on_hand if on_hand.positive?
|
||||
package.add variant, backordered, :backordered if backordered.positive?
|
||||
end
|
||||
|
||||
@@ -7,11 +7,10 @@ module OrderManagement
|
||||
RSpec.describe Package do
|
||||
context "base tests" do
|
||||
let(:variant) { build(:variant, weight: 25.0) }
|
||||
let(:stock_location) { build(:stock_location) }
|
||||
let(:distributor) { create(:enterprise) }
|
||||
let(:order) { build(:order, distributor:) }
|
||||
|
||||
subject { Package.new(stock_location, order) }
|
||||
subject { Package.new(order) }
|
||||
|
||||
it 'calculates the weight of all the contents' do
|
||||
subject.add variant, 4
|
||||
@@ -80,7 +79,7 @@ module OrderManagement
|
||||
Package::ContentItem.new(variant2, 1),
|
||||
Package::ContentItem.new(variant3, 1)]
|
||||
|
||||
package = Package.new(stock_location, order, contents)
|
||||
package = Package.new(order, contents)
|
||||
expect(package.shipping_methods.size).to eq 2
|
||||
end
|
||||
|
||||
@@ -96,7 +95,6 @@ module OrderManagement
|
||||
|
||||
shipment = subject.to_shipment
|
||||
expect(shipment.order).to eq subject.order
|
||||
expect(shipment.stock_location).to eq subject.stock_location
|
||||
expect(shipment.inventory_units.size).to eq 3
|
||||
|
||||
first_unit = shipment.inventory_units.first
|
||||
@@ -122,9 +120,7 @@ module OrderManagement
|
||||
end
|
||||
|
||||
context "#shipping_methods and #shipping_categories" do
|
||||
let(:stock_location) { double(:stock_location) }
|
||||
|
||||
subject(:package) { Package.new(stock_location, order, contents) }
|
||||
subject(:package) { Package.new(order, contents) }
|
||||
|
||||
let(:enterprise) { create(:enterprise) }
|
||||
let(:other_enterprise) { create(:enterprise) }
|
||||
|
||||
@@ -7,9 +7,8 @@ module OrderManagement
|
||||
RSpec.describe Packer do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:order) { create(:order_with_line_items, line_items_count: 5, distributor:) }
|
||||
let(:stock_location) { create(:stock_location) }
|
||||
|
||||
subject { Packer.new(stock_location, order) }
|
||||
subject { Packer.new(order) }
|
||||
|
||||
before { order.line_items.first.variant.update(unit_value: 100) }
|
||||
|
||||
@@ -21,7 +20,9 @@ module OrderManagement
|
||||
end
|
||||
|
||||
it 'variants are added as backordered without enough on_hand' do
|
||||
expect(stock_location).to receive(:fill_status).exactly(5).times.and_return([2, 3])
|
||||
order.line_items.each do |item|
|
||||
expect(item.variant).to receive(:fill_status).and_return([2, 3])
|
||||
end
|
||||
|
||||
package = subject.package
|
||||
expect(package.on_hand.size).to eq 5
|
||||
|
||||
@@ -6,12 +6,11 @@ module OrderManagement
|
||||
module Stock
|
||||
RSpec.describe Prioritizer do
|
||||
let(:order) { create(:order_with_line_items, line_items_count: 2) }
|
||||
let(:stock_location) { build(:stock_location) }
|
||||
let(:variant1) { order.line_items[0].variant }
|
||||
let(:variant2) { order.line_items[1].variant }
|
||||
|
||||
def pack
|
||||
package = Package.new(order, stock_location)
|
||||
package = Package.new(order)
|
||||
yield(package) if block_given?
|
||||
package
|
||||
end
|
||||
|
||||
@@ -42,10 +42,8 @@ RSpec.describe Api::V0::ProductsController, type: :controller do
|
||||
|
||||
api_get :show, id: product.to_param
|
||||
|
||||
expect(all_attributes.all?{ |attr| json_response.keys.include? attr }).to eq(true)
|
||||
expect(variants_attributes.all?{ |attr|
|
||||
json_response['variants'].first.keys.include? attr
|
||||
} ).to eq(true)
|
||||
expect(json_response.keys).to include(*all_attributes)
|
||||
expect(json_response["variants"].first.keys).to include(*variants_attributes)
|
||||
end
|
||||
|
||||
it "returns a 404 error when it cannot find a product" do
|
||||
|
||||
@@ -6,9 +6,7 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
render_views
|
||||
|
||||
let!(:shipment) { create(:shipment) }
|
||||
let!(:attributes) do
|
||||
[:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id]
|
||||
end
|
||||
let(:attributes) { %w[id tracking number cost shipped_at order_id] }
|
||||
let(:current_api_user) { build(:user) }
|
||||
|
||||
before do
|
||||
@@ -31,13 +29,11 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
let(:current_api_user) { build(:admin_user) }
|
||||
let!(:order) { shipment.order }
|
||||
let(:order_ship_address) { create(:address) }
|
||||
let!(:stock_location) { DefaultStockLocation.find_or_create }
|
||||
let!(:variant) { create(:variant) }
|
||||
let(:params) do
|
||||
{ quantity: 2,
|
||||
variant_id: variant.to_param,
|
||||
order_id: order.number,
|
||||
stock_location_id: stock_location.to_param,
|
||||
format: :json }
|
||||
end
|
||||
let(:error_message) { "broken shipments creation" }
|
||||
@@ -109,7 +105,7 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
allow_any_instance_of(Spree::Order).to receive_messages(paid?: true, complete?: true)
|
||||
api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param
|
||||
|
||||
expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy
|
||||
expect(json_response.keys).to include(*attributes)
|
||||
expect(json_response["state"]).to eq("ready")
|
||||
expect(shipment.reload.state).to eq("ready")
|
||||
end
|
||||
@@ -120,7 +116,7 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
|
||||
api_put :ready, order_id: shipment.order.to_param, id: shipment.to_param
|
||||
|
||||
expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy
|
||||
expect(json_response.keys).to include(*attributes)
|
||||
expect(json_response["state"]).to eq("ready")
|
||||
expect(shipment.reload.state).to eq("ready")
|
||||
end
|
||||
@@ -324,7 +320,7 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
id: shipment.to_param,
|
||||
shipment: { tracking: "123123" }
|
||||
|
||||
expect(attributes.all?{ |attr| json_response.key? attr.to_s }).to be_truthy
|
||||
expect(json_response.keys).to include(*attributes)
|
||||
expect(json_response["state"]).to eq("shipped")
|
||||
end
|
||||
end
|
||||
@@ -424,7 +420,7 @@ RSpec.describe Api::V0::ShipmentsController, type: :controller do
|
||||
|
||||
def expect_valid_response
|
||||
expect(response.status).to eq 200
|
||||
attributes.all?{ |attr| json_response.key? attr.to_s }
|
||||
expect(json_response.keys).to include(*attributes)
|
||||
end
|
||||
|
||||
def make_order_contents_fail
|
||||
|
||||
@@ -142,7 +142,6 @@ RSpec.describe Spree::Admin::ProductsController, type: :controller do
|
||||
|
||||
before do
|
||||
controller_login_as_admin
|
||||
create(:stock_location)
|
||||
end
|
||||
|
||||
it "redirects to products when the user hits 'create'" do
|
||||
|
||||
@@ -23,9 +23,6 @@ FactoryBot.define do
|
||||
variant_unit { 'weight' }
|
||||
variant_unit_scale { 1 }
|
||||
|
||||
# ensure stock item will be created for this products master
|
||||
before(:create) { DefaultStockLocation.find_or_create }
|
||||
|
||||
factory :product do
|
||||
transient do
|
||||
on_hand { 5 }
|
||||
|
||||
@@ -11,7 +11,6 @@ FactoryBot.define do
|
||||
state { 'pending' }
|
||||
order
|
||||
address
|
||||
stock_location { DefaultStockLocation.find_or_create }
|
||||
|
||||
after(:create) do |shipment, _evalulator|
|
||||
shipment.add_shipping_method(create(:shipping_method), true)
|
||||
@@ -31,7 +30,6 @@ FactoryBot.define do
|
||||
state { 'pending' }
|
||||
order
|
||||
address
|
||||
stock_location { DefaultStockLocation.find_or_create }
|
||||
|
||||
trait :shipping_method do
|
||||
transient do
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
FactoryBot.define do
|
||||
factory :stock_package, class: OrderManagement::Stock::Package do
|
||||
transient do
|
||||
stock_location { build(:stock_location) }
|
||||
order { create(:order_with_line_items, line_items_count: 2) }
|
||||
contents { [] }
|
||||
end
|
||||
|
||||
initialize_with { new(stock_location, order, contents) }
|
||||
initialize_with { new(order, contents) }
|
||||
|
||||
factory :stock_package_fulfilled do
|
||||
after(:build) do |package, evaluator|
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :stock_location, class: Spree::StockLocation do
|
||||
# keeps the test stock_location unique
|
||||
initialize_with { Spree::StockLocation.first || DefaultStockLocation.find_or_create }
|
||||
|
||||
address1 { '1600 Pennsylvania Ave NW' }
|
||||
city { 'Washington' }
|
||||
zipcode { '20500' }
|
||||
phone { '(202) 456-1111' }
|
||||
|
||||
country { |stock_location| Spree::Country.first || stock_location.association(:country) }
|
||||
state do |stock_location|
|
||||
stock_location.country.states.first ||
|
||||
stock_location.association(:state, country: stock_location.country)
|
||||
end
|
||||
|
||||
factory :stock_location_with_items do
|
||||
after(:create) do |stock_location, _evaluator|
|
||||
# variant will add itself to all stock_locations in an after_create
|
||||
# creating a product will automatically create a master variant
|
||||
product_1 = create(:product)
|
||||
product_2 = create(:product)
|
||||
|
||||
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
|
||||
end
|
||||
@@ -28,9 +28,6 @@ FactoryBot.define do
|
||||
# create a "standard variant"
|
||||
product { association :base_product }
|
||||
|
||||
# ensure stock item will be created for this variant
|
||||
before(:create) { DefaultStockLocation.find_or_create }
|
||||
|
||||
factory :variant do
|
||||
transient do
|
||||
on_demand { false }
|
||||
|
||||
@@ -12,7 +12,6 @@ RSpec.describe 'sample_data.rake' do
|
||||
before do
|
||||
# Create seed data required by the sample data.
|
||||
create(:user)
|
||||
DefaultStockLocation.find_or_create
|
||||
DefaultShippingCategory.find_or_create
|
||||
end
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ RSpec.describe VariantStock do
|
||||
it 'returns false' do
|
||||
variant = build_stubbed(
|
||||
:variant,
|
||||
stock_locations: [build_stubbed(:stock_location)]
|
||||
)
|
||||
expect(variant.on_demand).to be_falsy
|
||||
end
|
||||
@@ -94,9 +93,6 @@ RSpec.describe VariantStock do
|
||||
let(:variant) do
|
||||
build_stubbed(
|
||||
:variant,
|
||||
stock_locations: [
|
||||
build_stubbed(:stock_location)
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -148,7 +144,6 @@ RSpec.describe VariantStock do
|
||||
build_stubbed(
|
||||
:variant,
|
||||
on_demand: true,
|
||||
stock_locations: [build_stubbed(:stock_location)]
|
||||
)
|
||||
end
|
||||
let(:stock_item) { Spree::StockItem.new(backorderable: true) }
|
||||
@@ -172,7 +167,6 @@ RSpec.describe VariantStock do
|
||||
build_stubbed(
|
||||
:variant,
|
||||
on_demand: false,
|
||||
stock_locations: [build_stubbed(:stock_location)]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -3,50 +3,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Spree::InventoryUnit do
|
||||
let(:stock_location) { create(:stock_location_with_items) }
|
||||
let(:stock_item) { stock_location.stock_items.order(:id).first }
|
||||
|
||||
context "#backordered_for_stock_item" do
|
||||
let(:order) { create(:order) }
|
||||
|
||||
let(:shipment) do
|
||||
shipment = Spree::Shipment.new
|
||||
shipment.stock_location = stock_location
|
||||
shipment.shipping_methods << create(:shipping_method)
|
||||
shipment.order = order
|
||||
# We don't care about this in this test
|
||||
allow(shipment).to receive(:ensure_correct_adjustment)
|
||||
shipment.tap(&:save!)
|
||||
end
|
||||
|
||||
let!(:unit) do
|
||||
unit = shipment.inventory_units.build
|
||||
unit.state = 'backordered'
|
||||
unit.variant_id = stock_item.variant.id
|
||||
unit.tap(&:save!)
|
||||
end
|
||||
|
||||
# Regression for Spree #3066
|
||||
it "returns modifiable objects" do
|
||||
units = Spree::InventoryUnit.backordered_for_stock_item(stock_item)
|
||||
expect { units.first.save! }.not_to raise_error
|
||||
end
|
||||
|
||||
it "finds inventory units from its stock location " \
|
||||
"when the unit's variant matches the stock item's variant" do
|
||||
expect(Spree::InventoryUnit.backordered_for_stock_item(stock_item)).to eq [unit]
|
||||
end
|
||||
|
||||
it "does not find inventory units that don't match the stock item's variant" do
|
||||
other_variant_unit = shipment.inventory_units.build
|
||||
other_variant_unit.state = 'backordered'
|
||||
other_variant_unit.variant = create(:variant)
|
||||
other_variant_unit.save!
|
||||
|
||||
expect(Spree::InventoryUnit.backordered_for_stock_item(stock_item))
|
||||
.not_to include(other_variant_unit)
|
||||
end
|
||||
end
|
||||
let(:variant) { create(:variant) }
|
||||
let(:stock_item) { variant.stock_item }
|
||||
|
||||
context "variants deleted" do
|
||||
let!(:unit) do
|
||||
@@ -60,8 +18,6 @@ RSpec.describe Spree::InventoryUnit do
|
||||
end
|
||||
|
||||
context "#finalize_units!" do
|
||||
let!(:stock_location) { create(:stock_location) }
|
||||
let(:variant) { create(:variant) }
|
||||
let(:inventory_units) {
|
||||
[
|
||||
create(:inventory_unit, variant:),
|
||||
|
||||
@@ -36,13 +36,13 @@ RSpec.describe Spree::OrderInventory do
|
||||
before { allow(order).to receive_messages completed?: false }
|
||||
|
||||
it "doesn't unstock items" do
|
||||
expect(shipment.stock_location).not_to receive(:unstock)
|
||||
expect(line_item.variant).not_to receive(:move)
|
||||
expect(subject.__send__(:add_to_shipment, shipment, variant, 5)).to eq 5
|
||||
end
|
||||
end
|
||||
|
||||
it 'should create inventory_units in the necessary states' do
|
||||
expect(shipment.stock_location).to receive(:fill_status).with(variant, 5).and_return([3, 2])
|
||||
expect(variant).to receive(:fill_status).with(5).and_return([3, 2])
|
||||
|
||||
expect(subject.__send__(:add_to_shipment, shipment, variant, 5)).to eq 5
|
||||
|
||||
@@ -55,8 +55,7 @@ RSpec.describe Spree::OrderInventory do
|
||||
it 'should create stock_movement' do
|
||||
expect(subject.__send__(:add_to_shipment, shipment, variant, 5)).to eq 5
|
||||
|
||||
stock_item = shipment.stock_location.stock_item(variant)
|
||||
movement = stock_item.stock_movements.last
|
||||
movement = variant.stock_item.stock_movements.last
|
||||
expect(movement.quantity).to eq(-5)
|
||||
end
|
||||
end
|
||||
@@ -88,7 +87,7 @@ RSpec.describe Spree::OrderInventory do
|
||||
before { allow(order).to receive_messages completed?: false }
|
||||
|
||||
it "doesn't restock items" do
|
||||
expect(shipment.stock_location).not_to receive(:restock)
|
||||
expect(variant).not_to receive(:move)
|
||||
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
||||
end
|
||||
end
|
||||
@@ -97,7 +96,7 @@ RSpec.describe Spree::OrderInventory do
|
||||
before { allow(order).to receive_messages completed?: true }
|
||||
|
||||
it "doesn't restock items" do
|
||||
expect(shipment.stock_location).not_to receive(:restock)
|
||||
expect(variant).not_to receive(:move)
|
||||
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, false)).to eq 1
|
||||
end
|
||||
end
|
||||
@@ -105,8 +104,7 @@ RSpec.describe Spree::OrderInventory do
|
||||
it 'should create stock_movement' do
|
||||
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
||||
|
||||
stock_item = shipment.stock_location.stock_item(variant)
|
||||
movement = stock_item.stock_movements.last
|
||||
movement = variant.stock_item.stock_movements.last
|
||||
expect(movement.quantity).to eq 1
|
||||
end
|
||||
|
||||
|
||||
@@ -130,10 +130,6 @@ module Spree
|
||||
let!(:taxon){ create(:taxon) }
|
||||
let(:supplier){ create(:enterprise) }
|
||||
|
||||
before do
|
||||
create(:stock_location)
|
||||
end
|
||||
|
||||
it "copies properties to the first standard variant" do
|
||||
product.primary_taxon_id = taxon.id
|
||||
product.name = "Product1"
|
||||
|
||||
@@ -324,8 +324,7 @@ RSpec.describe Spree::Shipment do
|
||||
allow(shipment).to receive_message_chain(:inventory_units,
|
||||
:group_by,
|
||||
map: [unit])
|
||||
shipment.stock_location = build(:stock_location)
|
||||
expect(shipment.stock_location).to receive(:restock).with(variant, 1, shipment)
|
||||
expect(variant).to receive(:move).with(1, shipment)
|
||||
shipment.after_cancel
|
||||
end
|
||||
end
|
||||
@@ -348,8 +347,7 @@ RSpec.describe Spree::Shipment do
|
||||
allow(shipment).to receive_message_chain(:inventory_units,
|
||||
:group_by,
|
||||
map: [unit])
|
||||
shipment.stock_location = create(:stock_location)
|
||||
expect(shipment.stock_location).to receive(:unstock).with(variant, 1, shipment)
|
||||
expect(variant).to receive(:move).with(-1, shipment)
|
||||
shipment.after_resume
|
||||
end
|
||||
|
||||
|
||||
@@ -3,13 +3,9 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Spree::StockItem do
|
||||
let(:stock_location) { create(:stock_location_with_items) }
|
||||
|
||||
subject { stock_location.stock_items.order(:id).first }
|
||||
subject(:stock_item) { create(:variant, on_hand: 15).stock_item }
|
||||
|
||||
describe "validation" do
|
||||
let(:stock_item) { stock_location.stock_items.first }
|
||||
|
||||
it "requires count_on_hand to be positive if not backorderable" do
|
||||
stock_item.backorderable = false
|
||||
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
RSpec.describe StockLocation do
|
||||
subject { create(:stock_location_with_items) }
|
||||
let(:stock_item) { subject.stock_items.order(:id).first }
|
||||
let(:variant) { stock_item.variant }
|
||||
|
||||
it 'creates stock_items for all variants' do
|
||||
expect(subject.stock_items.count).to eq Variant.count
|
||||
end
|
||||
|
||||
context "handling stock items" do
|
||||
let!(:variant) { create(:variant) }
|
||||
|
||||
context "given a variant" do
|
||||
context "propagate all variants" do
|
||||
subject { StockLocation.new(name: "testing") }
|
||||
|
||||
specify do
|
||||
expect(subject.stock_items).to receive(:create!).at_least(:once)
|
||||
subject.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'finds a stock_item for a variant' do
|
||||
stock_item = subject.stock_item(variant)
|
||||
expect(stock_item.count_on_hand).to eq 15
|
||||
end
|
||||
|
||||
it 'finds a stock_item for a variant by id' do
|
||||
stock_item = subject.stock_item(variant.id)
|
||||
expect(stock_item.variant).to eq variant
|
||||
end
|
||||
|
||||
it 'returns nil when stock_item is not found for variant' do
|
||||
stock_item = subject.stock_item(100)
|
||||
expect(stock_item).to be_nil
|
||||
end
|
||||
|
||||
it 'finds a count_on_hand for a variant' do
|
||||
expect(subject.count_on_hand(variant)).to eq 15
|
||||
end
|
||||
|
||||
it 'finds determines if you a variant is backorderable' do
|
||||
expect(subject.backorderable?(variant)).to eq false
|
||||
end
|
||||
|
||||
it 'restocks a variant with a positive stock movement' do
|
||||
originator = double
|
||||
expect(subject).to receive(:move).with(variant, 5, originator)
|
||||
subject.restock(variant, 5, originator)
|
||||
end
|
||||
|
||||
it 'unstocks a variant with a negative stock movement' do
|
||||
originator = double
|
||||
expect(subject).to receive(:move).with(variant, -5, originator)
|
||||
subject.unstock(variant, 5, originator)
|
||||
end
|
||||
|
||||
it 'it creates a stock_movement' do
|
||||
variant.on_demand = false
|
||||
expect {
|
||||
subject.move variant, 5
|
||||
}.to change { subject.stock_movements.where(stock_item_id: stock_item).count }.by(1)
|
||||
end
|
||||
|
||||
context 'fill_status' do
|
||||
before { variant.on_demand = false }
|
||||
|
||||
it 'is all on_hand if variant is on_demand' do
|
||||
variant.on_demand = true
|
||||
|
||||
on_hand, backordered = subject.fill_status(variant, 25)
|
||||
expect(on_hand).to eq 25
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is all on_hand if on_hand is enough' do
|
||||
on_hand, backordered = subject.fill_status(variant, 5)
|
||||
expect(on_hand).to eq 5
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is some on_hand if not all available' do
|
||||
on_hand, backordered = subject.fill_status(variant, 20)
|
||||
expect(on_hand).to eq 15
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is zero on_hand if none available' do
|
||||
variant.on_hand = 0
|
||||
|
||||
on_hand, backordered = subject.fill_status(variant, 20)
|
||||
expect(on_hand).to eq 0
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,8 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Spree::StockMovement do
|
||||
let(:stock_location) { create(:stock_location_with_items) }
|
||||
let(:stock_item) { stock_location.stock_items.order(:id).first }
|
||||
let(:stock_item) { create(:variant, on_hand: 15).stock_item }
|
||||
subject { build(:stock_movement, stock_item:) }
|
||||
|
||||
it 'should belong to a stock item' do
|
||||
|
||||
@@ -12,7 +12,6 @@ RSpec.describe Spree::Variant do
|
||||
it { is_expected.to have_many(:inventory_units) }
|
||||
it { is_expected.to have_many(:line_items) }
|
||||
it { is_expected.to have_many(:stock_items) }
|
||||
it { is_expected.to have_many(:stock_locations).through(:stock_items) }
|
||||
it { is_expected.to have_many(:images) }
|
||||
it { is_expected.to have_one(:default_price) }
|
||||
it { is_expected.to have_many(:prices) }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Spree::Variant do
|
||||
# This method is defined in app/models/concerns/variant_stock.rb.
|
||||
# These methods are defined in app/models/concerns/variant_stock.rb.
|
||||
# There is a separate spec for that concern but here I want to test
|
||||
# the interplay of Spree::Variant and VariantOverride.
|
||||
#
|
||||
@@ -11,6 +11,38 @@ RSpec.describe Spree::Variant do
|
||||
# like this one get overridden. Future calls to `variant.move` are then
|
||||
# handled by the ScopeVariantToHub module which may call the
|
||||
# VariantOverride.
|
||||
describe "#fill_status" do
|
||||
subject(:variant) { create(:variant, on_hand: 15) }
|
||||
|
||||
it 'is all on_hand if variant is on_demand' do
|
||||
variant.on_demand = true
|
||||
|
||||
on_hand, backordered = subject.fill_status(25)
|
||||
expect(on_hand).to eq 25
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is all on_hand if on_hand is enough' do
|
||||
on_hand, backordered = subject.fill_status(5)
|
||||
expect(on_hand).to eq 5
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is some on_hand if not all available' do
|
||||
on_hand, backordered = subject.fill_status(20)
|
||||
expect(on_hand).to eq 15
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
|
||||
it 'is zero on_hand if none available' do
|
||||
variant.on_hand = 0
|
||||
|
||||
on_hand, backordered = subject.fill_status(20)
|
||||
expect(on_hand).to eq 0
|
||||
expect(backordered).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "#move" do
|
||||
subject(:variant) { create(:variant, on_hand: 5) }
|
||||
|
||||
|
||||
@@ -22,10 +22,4 @@ RSpec.describe Api::Admin::VariantSerializer do
|
||||
|
||||
expect(serializer.to_json).to match variant.full_name
|
||||
end
|
||||
|
||||
it "serializes the variant stock location id" do
|
||||
serializer = Api::Admin::VariantSerializer.new variant
|
||||
|
||||
expect(serializer.to_json).to match variant.stock_items.first.stock_location.id.to_s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe DefaultStockLocation do
|
||||
describe '.find_or_create' do
|
||||
context 'when a location named default already exists' do
|
||||
let!(:location) do
|
||||
country = create(:country)
|
||||
state = Spree::State.create(name: 'Alabama', country:)
|
||||
Spree::StockLocation.create!(
|
||||
name: 'default',
|
||||
country_id: country.id,
|
||||
state_id: state.id
|
||||
)
|
||||
end
|
||||
|
||||
it 'returns the location' do
|
||||
expect(described_class.find_or_create).to eq(location)
|
||||
end
|
||||
|
||||
it 'does not create any other location' do
|
||||
expect { described_class.find_or_create }.not_to change { Spree::StockLocation.count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a location named default does not exist' do
|
||||
it 'returns the location' do
|
||||
location = described_class.find_or_create
|
||||
expect(location.name).to eq('default')
|
||||
end
|
||||
|
||||
it 'does not create any other location' do
|
||||
expect { described_class.find_or_create }
|
||||
.to change { Spree::StockLocation.count }.from(0).to(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,6 @@ RSpec.describe Sets::ProductSet do
|
||||
subject{ product_set.save }
|
||||
|
||||
context 'when the product does not exist yet' do
|
||||
let!(:stock_location) { create(:stock_location) }
|
||||
let(:collection_hash) do
|
||||
{
|
||||
0 => {
|
||||
|
||||
@@ -1100,7 +1100,7 @@ RSpec.describe '
|
||||
end
|
||||
|
||||
it "the user can confirm : line item is then deleted and order is canceled" do
|
||||
expect_any_instance_of(Spree::StockLocation).to receive(:restock).at_least(1).times
|
||||
expect_any_instance_of(Spree::Variant).to receive(:move).at_least(1).times
|
||||
expect do
|
||||
within(".modal") do
|
||||
uncheck("send_cancellation_email")
|
||||
@@ -1113,7 +1113,7 @@ RSpec.describe '
|
||||
|
||||
it "the user can confirm + wants to send email confirmation : line item is " \
|
||||
"then deleted, order is canceled and email is sent" do
|
||||
expect_any_instance_of(Spree::StockLocation).to receive(:restock).at_least(1).times
|
||||
expect_any_instance_of(Spree::Variant).to receive(:move).at_least(1).times
|
||||
expect do
|
||||
within(".modal") do
|
||||
check("send_cancellation_email")
|
||||
@@ -1126,7 +1126,7 @@ RSpec.describe '
|
||||
|
||||
it "the user can confirm + uncheck the restock option: line item is then deleted and " \
|
||||
"order is canceled without retocking" do
|
||||
expect_any_instance_of(Spree::StockLocation).not_to receive(:restock)
|
||||
expect_any_instance_of(Spree::Variant).not_to receive(:move)
|
||||
expect do
|
||||
within(".modal") do
|
||||
uncheck("Restock Items: return all items to stock")
|
||||
|
||||
@@ -218,7 +218,6 @@ RSpec.describe '
|
||||
let(:shipment) { order.shipments.first }
|
||||
|
||||
it "and by default an Email is sent and the items are restocked" do
|
||||
expect_any_instance_of(Spree::StockLocation).to receive(:restock).at_least(1).times
|
||||
expect do
|
||||
within(".modal") do
|
||||
click_on("OK")
|
||||
@@ -226,10 +225,10 @@ RSpec.describe '
|
||||
expect(page).to have_content "Cannot add item to canceled order"
|
||||
expect(order.reload.state).to eq("canceled")
|
||||
end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email)
|
||||
.and change { Spree::StockItem.pluck(:count_on_hand) }
|
||||
end
|
||||
|
||||
it "and then the order is cancelled and email is not sent when unchecked" do
|
||||
expect_any_instance_of(Spree::StockLocation).to receive(:restock).at_least(1).times
|
||||
expect do
|
||||
within(".modal") do
|
||||
uncheck("send_cancellation_email")
|
||||
@@ -237,11 +236,12 @@ RSpec.describe '
|
||||
end
|
||||
expect(page).to have_content "Cannot add item to canceled order"
|
||||
expect(order.reload.state).to eq("canceled")
|
||||
end.not_to have_enqueued_mail(Spree::OrderMailer, :cancel_email)
|
||||
end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email).at_most(0).times
|
||||
.and change { Spree::StockItem.pluck(:count_on_hand) }
|
||||
end
|
||||
|
||||
it "and the items are not restocked when the user uncheck the checkbox to restock items" do
|
||||
expect_any_instance_of(Spree::StockLocation).not_to receive(:restock)
|
||||
expect_any_instance_of(Spree::Variant).not_to receive(:move)
|
||||
expect do
|
||||
within(".modal") do
|
||||
uncheck("restock_items")
|
||||
@@ -250,6 +250,8 @@ RSpec.describe '
|
||||
expect(page).to have_content "Cannot add item to canceled order"
|
||||
expect(order.reload.state).to eq("canceled")
|
||||
end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email)
|
||||
# Not change stock. Rspec can't combine `to` and `not_to` though.
|
||||
.and change { Spree::StockItem.pluck(:count_on_hand) }.by([])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,6 @@ RSpec.describe '
|
||||
include FileHelper
|
||||
|
||||
let!(:taxon) { create(:taxon) }
|
||||
let!(:stock_location) { create(:stock_location) }
|
||||
let!(:shipping_category) { DefaultShippingCategory.find_or_create }
|
||||
let!(:supplier) { create(:supplier_enterprise, name: 'New supplier') }
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ RSpec.describe 'As an enterprise user, I can manage my products' do
|
||||
let!(:taxon) { create(:taxon) }
|
||||
|
||||
describe "creating a new product" do
|
||||
let!(:stock_location) { create(:stock_location) }
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:shipping_category) { create(:shipping_category) }
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ RSpec.describe '
|
||||
include AuthenticationHelper
|
||||
include WebHelper
|
||||
|
||||
let!(:stock_location) { create(:stock_location) }
|
||||
|
||||
describe "product" do
|
||||
it "creating a new product" do
|
||||
login_as_admin
|
||||
|
||||
Reference in New Issue
Block a user