Bring Spree::StockItem code from spree_core into the app

This commit is contained in:
Kristina Lim
2020-05-14 04:13:21 +08:00
committed by Luis Ramos
parent 9e730e6445
commit 0e711832fd
2 changed files with 126 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
module Spree
class StockItem < ActiveRecord::Base
belongs_to :stock_location, class_name: 'Spree::StockLocation'
belongs_to :variant, class_name: 'Spree::Variant'
has_many :stock_movements, dependent: :destroy
validates_presence_of :stock_location, :variant
validates_uniqueness_of :variant_id, scope: :stock_location_id
attr_accessible :count_on_hand, :variant, :stock_location, :backorderable, :variant_id
delegate :weight, to: :variant
def backordered_inventory_units
Spree::InventoryUnit.backordered_for_stock_item(self)
end
def variant_name
variant.name
end
def adjust_count_on_hand(value)
self.with_lock do
self.count_on_hand = self.count_on_hand + value
process_backorders if in_stock?
self.save!
end
end
def in_stock?
self.count_on_hand > 0
end
# Tells whether it's available to be included in a shipment
def available?
self.in_stock? || self.backorderable?
end
private
def count_on_hand=(value)
write_attribute(:count_on_hand, value)
end
def process_backorders
backordered_inventory_units.each do |unit|
return unless in_stock?
unit.fill_backorder
end
end
end
end

View File

@@ -0,0 +1,74 @@
require 'spec_helper'
describe Spree::StockItem do
let(:stock_location) { create(:stock_location_with_items) }
subject { stock_location.stock_items.order(:id).first }
it 'maintains the count on hand for a variant' do
subject.count_on_hand.should eq 10
end
it "can return the stock item's variant's name" do
subject.variant_name.should == subject.variant.name
end
context "available to be included in shipment" do
context "has stock" do
it { subject.should be_available }
end
context "backorderable" do
before { subject.backorderable = true }
it { subject.should be_available }
end
context "no stock and not backorderable" do
before do
subject.backorderable = false
subject.stub(count_on_hand: 0)
end
it { subject.should_not be_available }
end
end
context "adjust count_on_hand" do
let!(:current_on_hand) { subject.count_on_hand }
it 'is updated pessimistically' do
copy = Spree::StockItem.find(subject.id)
subject.adjust_count_on_hand(5)
subject.count_on_hand.should eq(current_on_hand + 5)
copy.count_on_hand.should eq(current_on_hand)
copy.adjust_count_on_hand(5)
copy.count_on_hand.should eq(current_on_hand + 10)
end
context "item out of stock (by two items)" do
let(:inventory_unit) { double('InventoryUnit') }
let(:inventory_unit_2) { double('InventoryUnit2') }
before { subject.adjust_count_on_hand(- (current_on_hand + 2)) }
it "doesn't process backorders" do
subject.should_not_receive(:backordered_inventory_units)
subject.adjust_count_on_hand(1)
end
context "adds new items" do
before { subject.stub(:backordered_inventory_units => [inventory_unit, inventory_unit_2]) }
it "fills existing backorders" do
inventory_unit.should_receive(:fill_backorder)
inventory_unit_2.should_receive(:fill_backorder)
subject.adjust_count_on_hand(3)
subject.count_on_hand.should == 1
end
end
end
end
end