solidus_product_assembly 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.travis.yml +21 -0
- data/Gemfile +18 -0
- data/LICENSE.md +13 -0
- data/README.md +80 -0
- data/Rakefile +21 -0
- data/app/assets/images/spinner.gif +0 -0
- data/app/assets/javascripts/spree/backend/solidus_product_assembly.js +1 -0
- data/app/assets/javascripts/spree/frontend/solidus_product_assembly.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_product_assembly.css +3 -0
- data/app/assets/stylesheets/spree/frontend/solidus_product_assembly.css +3 -0
- data/app/controllers/spree/admin/parts_controller.rb +49 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +9 -0
- data/app/helpers/spree/admin/orders_helper_decorator.rb +9 -0
- data/app/models/spree/assemblies_part.rb +12 -0
- data/app/models/spree/inventory_unit_decorator.rb +13 -0
- data/app/models/spree/line_item_decorator.rb +44 -0
- data/app/models/spree/order_inventory_assembly.rb +39 -0
- data/app/models/spree/product_decorator.rb +56 -0
- data/app/models/spree/shipment_decorator.rb +50 -0
- data/app/models/spree/stock/availability_validator.rb +28 -0
- data/app/models/spree/stock/inventory_unit_builder_decorator.rb +30 -0
- data/app/models/spree/stock/inventory_validator_decorator.rb +12 -0
- data/app/models/spree/variant_decorator.rb +13 -0
- data/app/overrides/add_admin_product_form_fields.rb +5 -0
- data/app/overrides/add_admin_tabs.rb +5 -0
- data/app/overrides/add_line_item_description.rb +5 -0
- data/app/overrides/spree/admin/orders/_form/inject_product_assemblies.html.erb.deface +3 -0
- data/app/overrides/spree/admin/orders/_shipment/stock_contents.html.erb.deface +2 -0
- data/app/overrides/spree/checkout/_delivery/remove_unshippable_markup.html.erb.deface +1 -0
- data/app/overrides/spree/checkout/_delivery/render_line_item_manifest.html.erb.deface +3 -0
- data/app/overrides/spree/products/show/add_links_to_parts.html.erb.deface +21 -0
- data/app/overrides/spree/products/show/remove_add_to_cart_button_for_non_individual_sale_products.html.erb.deface +4 -0
- data/app/overrides/spree/shared/_order_details/part_description.html.erb.deface +8 -0
- data/app/views/spree/admin/orders/_assemblies.html.erb +56 -0
- data/app/views/spree/admin/orders/_stock_contents.html.erb +69 -0
- data/app/views/spree/admin/orders/_stock_item.html.erb +46 -0
- data/app/views/spree/admin/parts/_parts_table.html.erb +33 -0
- data/app/views/spree/admin/parts/available.html.erb +55 -0
- data/app/views/spree/admin/parts/available.js.erb +54 -0
- data/app/views/spree/admin/parts/index.html.erb +70 -0
- data/app/views/spree/admin/parts/update_parts_table.js.erb +2 -0
- data/app/views/spree/admin/products/_product_assembly_fields.html.erb +23 -0
- data/app/views/spree/admin/shared/_product_assembly_product_tabs.html.erb +3 -0
- data/app/views/spree/checkout/_line_item_manifest.html.erb +17 -0
- data/app/views/spree/orders/_cart_description.html.erb +8 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +14 -0
- data/config/locales/fr.yml +12 -0
- data/config/locales/ru.yml +12 -0
- data/config/locales/sv.yml +12 -0
- data/config/routes.rb +19 -0
- data/db/migrate/20091028152124_add_many_to_many_relation_to_products.rb +13 -0
- data/db/migrate/20091029165620_add_parts_fields_to_products.rb +27 -0
- data/db/migrate/20120316141830_namespace_product_assembly_for_spree_one.rb +9 -0
- data/db/migrate/20140620223938_add_id_to_spree_assemblies_parts.rb +9 -0
- data/lib/generators/solidus_product_assembly/install/install_generator.rb +24 -0
- data/lib/solidus_product_assembly.rb +3 -0
- data/lib/solidus_product_assembly/engine.rb +15 -0
- data/lib/solidus_product_assembly/version.rb +3 -0
- data/lib/tasks/spree2_upgrade.rake +29 -0
- data/solidus_product_assembly.gemspec +35 -0
- data/spec/features/admin/orders_spec.rb +29 -0
- data/spec/features/admin/parts_spec.rb +28 -0
- data/spec/features/checkout_spec.rb +92 -0
- data/spec/models/spree/assemblies_part_spec.rb +18 -0
- data/spec/models/spree/inventory_unit_spec.rb +32 -0
- data/spec/models/spree/line_item_spec.rb +72 -0
- data/spec/models/spree/order_contents_spec.rb +40 -0
- data/spec/models/spree/order_inventory_assembly_spec.rb +55 -0
- data/spec/models/spree/order_inventory_spec.rb +35 -0
- data/spec/models/spree/product_spec.rb +35 -0
- data/spec/models/spree/shipment_spec.rb +112 -0
- data/spec/models/spree/stock/availability_validator_spec.rb +71 -0
- data/spec/models/spree/stock/coordinator_spec.rb +52 -0
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +36 -0
- data/spec/models/spree/variant_spec.rb +28 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/support/shared_contexts/order_with_bundle.rb +13 -0
- metadata +272 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Checkout", type: :feature do
|
4
|
+
let!(:store) { create :store, default: true }
|
5
|
+
let!(:country) { create(:country, :name => "United States", :states_required => true) }
|
6
|
+
let!(:state) { create(:state, :name => "Ohio", :country => country) }
|
7
|
+
let!(:shipping_method) { create(:shipping_method) }
|
8
|
+
let!(:stock_location) { create(:stock_location) }
|
9
|
+
let!(:payment_method) { create(:check_payment_method) }
|
10
|
+
let!(:zone) { create(:zone) }
|
11
|
+
|
12
|
+
let(:product) { create(:product, :name => "RoR Mug") }
|
13
|
+
let(:variant) { create(:variant) }
|
14
|
+
|
15
|
+
stub_authorization!
|
16
|
+
|
17
|
+
before { product.parts << variant << create(:variant) }
|
18
|
+
|
19
|
+
shared_context "purchases product with part included" do
|
20
|
+
before do
|
21
|
+
add_product_to_cart
|
22
|
+
click_button "Checkout"
|
23
|
+
|
24
|
+
fill_in "order_email", :with => "ryan@spreecommerce.com"
|
25
|
+
click_button "Continue"
|
26
|
+
fill_in_address
|
27
|
+
|
28
|
+
click_button "Save and Continue"
|
29
|
+
expect(current_path).to eql(spree.checkout_state_path("delivery"))
|
30
|
+
page.should have_content(variant.product.name)
|
31
|
+
|
32
|
+
click_button "Save and Continue"
|
33
|
+
expect(current_path).to eql(spree.checkout_state_path("payment"))
|
34
|
+
|
35
|
+
click_button "Save and Continue"
|
36
|
+
expect(current_path).to eq spree.checkout_state_path('confirm')
|
37
|
+
page.should have_content(variant.product.name)
|
38
|
+
|
39
|
+
click_button "Place Order"
|
40
|
+
page.should have_content('Your order has been processed successfully')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "backend order shipments UI", js: true do
|
45
|
+
|
46
|
+
context "ordering only the product assembly" do
|
47
|
+
include_context "purchases product with part included"
|
48
|
+
|
49
|
+
it "views parts bundled as well" do
|
50
|
+
visit spree.admin_orders_path
|
51
|
+
click_on Spree::Order.last.number
|
52
|
+
|
53
|
+
page.should have_content(variant.product.name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "ordering assembly and the part as individual sale" do
|
58
|
+
before do
|
59
|
+
visit spree.root_path
|
60
|
+
click_link variant.product.name
|
61
|
+
click_button "add-to-cart-button"
|
62
|
+
end
|
63
|
+
include_context "purchases product with part included"
|
64
|
+
|
65
|
+
it "views parts bundled and not" do
|
66
|
+
visit spree.admin_orders_path
|
67
|
+
click_on Spree::Order.last.number
|
68
|
+
|
69
|
+
page.should have_content(variant.product.name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def fill_in_address
|
77
|
+
address = "order_bill_address_attributes"
|
78
|
+
fill_in "#{address}_firstname", :with => "Ryan"
|
79
|
+
fill_in "#{address}_lastname", :with => "Bigg"
|
80
|
+
fill_in "#{address}_address1", :with => "143 Swan Street"
|
81
|
+
fill_in "#{address}_city", :with => "Richmond"
|
82
|
+
select "Ohio", :from => "#{address}_state_id"
|
83
|
+
fill_in "#{address}_zipcode", :with => "12345"
|
84
|
+
fill_in "#{address}_phone", :with => "(555) 555-5555"
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_product_to_cart
|
88
|
+
visit spree.root_path
|
89
|
+
click_link product.name
|
90
|
+
click_button "add-to-cart-button"
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe AssembliesPart do
|
5
|
+
let(:product) { create(:product) }
|
6
|
+
let(:variant) { create(:variant) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
product.parts.push variant
|
10
|
+
end
|
11
|
+
|
12
|
+
context "get" do
|
13
|
+
it "brings part by product and variant id" do
|
14
|
+
subject.class.get(product.id, variant.id).part.should == variant
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe InventoryUnit do
|
5
|
+
let!(:order) { create(:order_with_line_items) }
|
6
|
+
let(:line_item) { order.line_items.first }
|
7
|
+
let(:product) { line_item.product }
|
8
|
+
|
9
|
+
subject { InventoryUnit.create(line_item: line_item, variant: line_item.variant, order: order) }
|
10
|
+
|
11
|
+
context 'if the unit is not part of an assembly' do
|
12
|
+
it 'it will return the percentage of a line item' do
|
13
|
+
expect(subject.percentage_of_line_item).to eql(BigDecimal.new(1))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'if part of an assembly' do
|
18
|
+
let(:parts) { (1..2).map { create(:variant) } }
|
19
|
+
|
20
|
+
before do
|
21
|
+
product.parts << parts
|
22
|
+
order.create_proposed_shipments
|
23
|
+
order.finalize!
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'it will return the percentage of a line item' do
|
27
|
+
subject.line_item = line_item
|
28
|
+
expect(subject.percentage_of_line_item).to eql(BigDecimal.new(0.5, 2))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe LineItem do
|
5
|
+
let!(:order) { create(:order_with_line_items) }
|
6
|
+
let(:line_item) { order.line_items.first }
|
7
|
+
let(:product) { line_item.product }
|
8
|
+
let(:variant) { line_item.variant }
|
9
|
+
let(:inventory) { double('order_inventory') }
|
10
|
+
|
11
|
+
context "bundle parts stock" do
|
12
|
+
let(:parts) { (1..2).map { create(:variant) } }
|
13
|
+
|
14
|
+
before { product.parts << parts }
|
15
|
+
|
16
|
+
context "one of them not in stock" do
|
17
|
+
before do
|
18
|
+
part = product.parts.first
|
19
|
+
part.stock_items.update_all backorderable: false
|
20
|
+
|
21
|
+
expect(part).not_to be_in_stock
|
22
|
+
end
|
23
|
+
|
24
|
+
it "doesn't save line item quantity" do
|
25
|
+
order.contents.add(variant, 10)
|
26
|
+
expect { order.contents.advance }.to raise_error Spree::Order::InsufficientStock
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "in stock" do
|
31
|
+
before do
|
32
|
+
parts.each do |part|
|
33
|
+
part.stock_items.first.set_count_on_hand(10)
|
34
|
+
end
|
35
|
+
expect(parts[0]).to be_in_stock
|
36
|
+
expect(parts[1]).to be_in_stock
|
37
|
+
end
|
38
|
+
|
39
|
+
it "saves line item quantity" do
|
40
|
+
line_item = order.contents.add(variant, 10)
|
41
|
+
expect(line_item).to be_valid
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "updates bundle product line item" do
|
47
|
+
let(:parts) { (1..2).map { create(:variant) } }
|
48
|
+
|
49
|
+
before do
|
50
|
+
product.parts << parts
|
51
|
+
order.create_proposed_shipments
|
52
|
+
order.finalize!
|
53
|
+
end
|
54
|
+
|
55
|
+
it "verifies inventory units via OrderInventoryAssembly" do
|
56
|
+
OrderInventoryAssembly.should_receive(:new).with(line_item).and_return(inventory)
|
57
|
+
inventory.should_receive(:verify).with(line_item.target_shipment)
|
58
|
+
line_item.quantity = 2
|
59
|
+
line_item.save
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "updates regular line item" do
|
64
|
+
it "verifies inventory units via OrderInventory" do
|
65
|
+
OrderInventory.should_receive(:new).with(line_item.order, line_item).and_return(inventory)
|
66
|
+
inventory.should_receive(:verify).with(line_item.target_shipment)
|
67
|
+
line_item.quantity = 2
|
68
|
+
line_item.save
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe OrderContents do
|
5
|
+
let!(:store) { create :store }
|
6
|
+
let(:order) { Order.create }
|
7
|
+
|
8
|
+
let(:guitar) { create(:variant) }
|
9
|
+
let(:bass) { create(:variant) }
|
10
|
+
|
11
|
+
let(:bundle) { create(:product) }
|
12
|
+
|
13
|
+
subject { OrderContents.new(order) }
|
14
|
+
|
15
|
+
before { bundle.parts.push [guitar, bass] }
|
16
|
+
|
17
|
+
context "same variant within bundle and as regular product" do
|
18
|
+
let!(:guitar_item) { subject.add(guitar, 3) }
|
19
|
+
let!(:bundle_item) { subject.add(bundle.master, 5) }
|
20
|
+
|
21
|
+
it "destroys the variant as regular product only" do
|
22
|
+
subject.remove(guitar, 3)
|
23
|
+
expect(order.reload.line_items.to_a).to eq [bundle_item]
|
24
|
+
end
|
25
|
+
|
26
|
+
context "completed order" do
|
27
|
+
before do
|
28
|
+
order.create_proposed_shipments
|
29
|
+
order.touch :completed_at
|
30
|
+
end
|
31
|
+
|
32
|
+
it "destroys accurate number of inventory units" do
|
33
|
+
expect {
|
34
|
+
subject.remove(guitar, 3)
|
35
|
+
}.to change { InventoryUnit.count }.by(-3)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe OrderInventoryAssembly do
|
5
|
+
let(:order) { create(:order_with_line_items) }
|
6
|
+
let(:line_item) { order.line_items.first }
|
7
|
+
let(:bundle) { line_item.product }
|
8
|
+
let(:parts) { (1..3).map { create(:variant) } }
|
9
|
+
|
10
|
+
before do
|
11
|
+
bundle.parts << [parts]
|
12
|
+
bundle.set_part_count(parts.first, 3)
|
13
|
+
|
14
|
+
line_item.update_attributes!(quantity: 3)
|
15
|
+
order.reload.create_proposed_shipments
|
16
|
+
order.finalize!
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { OrderInventoryAssembly.new(line_item) }
|
20
|
+
|
21
|
+
context "inventory units count" do
|
22
|
+
it "calculates the proper value for the bundle" do
|
23
|
+
expected_units_count = line_item.quantity * bundle.assemblies_parts.to_a.sum(&:count)
|
24
|
+
expect(subject.inventory_units.count).to eql(expected_units_count)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "verify line item units" do
|
29
|
+
let!(:original_units_count) { subject.inventory_units.count }
|
30
|
+
|
31
|
+
context "quantity increases" do
|
32
|
+
before { subject.line_item.quantity += 1 }
|
33
|
+
|
34
|
+
it "inserts new inventory units for every bundle part" do
|
35
|
+
expected_units_count = original_units_count + bundle.assemblies_parts.to_a.sum(&:count)
|
36
|
+
subject.verify
|
37
|
+
expect(OrderInventoryAssembly.new(line_item.reload).inventory_units.count).to eql(expected_units_count)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "quantity decreases" do
|
42
|
+
before { subject.line_item.quantity -= 1 }
|
43
|
+
|
44
|
+
it "remove inventory units for every bundle part" do
|
45
|
+
expected_units_count = original_units_count - bundle.assemblies_parts.to_a.sum(&:count)
|
46
|
+
subject.verify
|
47
|
+
|
48
|
+
# needs to reload so that inventory units are fetched from updates order.shipments
|
49
|
+
updated_units_count = OrderInventoryAssembly.new(line_item.reload).inventory_units.count
|
50
|
+
expect(updated_units_count).to eql(expected_units_count)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe OrderInventory do
|
5
|
+
let!(:store) { create :store }
|
6
|
+
let(:order) { Order.create }
|
7
|
+
|
8
|
+
subject { OrderInventory.new(order, order.line_items.first) }
|
9
|
+
|
10
|
+
context "same variant within bundle and as regular product" do
|
11
|
+
let(:contents) { OrderContents.new(order) }
|
12
|
+
let(:guitar) { create(:variant) }
|
13
|
+
let(:bass) { create(:variant) }
|
14
|
+
|
15
|
+
let(:bundle) { create(:product) }
|
16
|
+
|
17
|
+
before { bundle.parts.push [guitar, bass] }
|
18
|
+
|
19
|
+
let!(:bundle_item) { contents.add(bundle.master, 5) }
|
20
|
+
let!(:guitar_item) { contents.add(guitar, 3) }
|
21
|
+
|
22
|
+
let!(:shipment) { order.create_proposed_shipments.first }
|
23
|
+
|
24
|
+
context "completed order" do
|
25
|
+
before { order.touch :completed_at }
|
26
|
+
|
27
|
+
it "removes only units associated with provided line item" do
|
28
|
+
expect {
|
29
|
+
subject.send(:remove_from_shipment, shipment, 5)
|
30
|
+
}.not_to change { bundle_item.inventory_units.count }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Product do
|
4
|
+
before(:each) do
|
5
|
+
@product = FactoryGirl.create(:product, :name => "Foo Bar")
|
6
|
+
@master_variant = Spree::Variant.where(is_master: true).find_by_product_id(@product.id)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "Spree::Product Assembly" do
|
10
|
+
before(:each) do
|
11
|
+
@product = create(:product)
|
12
|
+
@part1 = create(:product, :can_be_part => true)
|
13
|
+
@part2 = create(:product, :can_be_part => true)
|
14
|
+
@product.add_part @part1.master, 1
|
15
|
+
@product.add_part @part2.master, 4
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is an assembly" do
|
19
|
+
@product.should be_assembly
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
it "cannot be part" do
|
24
|
+
@product.should be_assembly
|
25
|
+
@product.can_be_part = true
|
26
|
+
@product.valid?
|
27
|
+
@product.errors[:can_be_part].should == ["assembly can't be part"]
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'changing part qty changes count on_hand' do
|
31
|
+
@product.set_part_count(@part2.master, 2)
|
32
|
+
@product.count_of(@part2.master).should == 2
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe Shipment do
|
5
|
+
context "order has one product assembly" do
|
6
|
+
let(:order) { Order.create }
|
7
|
+
let(:bundle) { create(:variant) }
|
8
|
+
let!(:parts) { (1..2).map { create(:variant) } }
|
9
|
+
let!(:bundle_parts) { bundle.product.parts << parts }
|
10
|
+
|
11
|
+
let!(:line_item) { order.contents.add(bundle, 1) }
|
12
|
+
let!(:shipment) { order.create_proposed_shipments.first }
|
13
|
+
|
14
|
+
before { order.update_column :state, 'complete' }
|
15
|
+
|
16
|
+
it "shipment item cost equals line item amount" do
|
17
|
+
expect(shipment.item_cost).to eq line_item.amount
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "manifests" do
|
22
|
+
include_context "product is ordered as individual and within a bundle"
|
23
|
+
|
24
|
+
let(:shipments) { order.create_proposed_shipments }
|
25
|
+
|
26
|
+
context "default" do
|
27
|
+
let(:expected_variants) { order.variants - [bundle_variant] + bundle.parts }
|
28
|
+
|
29
|
+
it "separates variant purchased individually from the bundle one" do
|
30
|
+
expect(shipments.count).to eql 1
|
31
|
+
shipments.first.manifest.map(&:variant).sort.should == expected_variants.sort
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "line items manifest" do
|
36
|
+
let(:expected_variants) { order.variants }
|
37
|
+
|
38
|
+
it "groups units by line_item only" do
|
39
|
+
expect(shipments.count).to eql 1
|
40
|
+
shipments.first.line_item_manifest.map(&:variant).sort.should == expected_variants.sort
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "units are not associated with a line item" do
|
45
|
+
let(:order) { create(:shipped_order) }
|
46
|
+
let(:shipment) { order.shipments.first }
|
47
|
+
|
48
|
+
it "searches for line item if inventory unit doesn't have one" do
|
49
|
+
shipment.manifest.last.line_item.should_not be_blank
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "set up new inventory units" do
|
55
|
+
let(:line_item) { create(:line_item) }
|
56
|
+
let(:variant) { line_item.variant }
|
57
|
+
let(:order) { line_item.order }
|
58
|
+
let(:shipment) { create(:shipment) }
|
59
|
+
|
60
|
+
it "assigns variant, order and line_item" do
|
61
|
+
unit = shipment.set_up_inventory('on_hand', variant, order, line_item)
|
62
|
+
|
63
|
+
expect(unit.line_item).to eq line_item
|
64
|
+
expect(unit.variant).to eq variant
|
65
|
+
expect(unit.order).to eq order
|
66
|
+
expect(unit.state).to eq 'on_hand'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "unit states for variant sold as part of an assembly and separately" do
|
71
|
+
let(:assembly_line_item) { create(:line_item) }
|
72
|
+
let(:shirt) { create(:variant) }
|
73
|
+
|
74
|
+
let(:assembly_shirts) do
|
75
|
+
5.times.map {
|
76
|
+
create(:inventory_unit,
|
77
|
+
variant: shirt,
|
78
|
+
line_item: assembly_line_item,
|
79
|
+
state: :on_hand)
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
let(:standalone_line_item) { create(:line_item, variant: shirt) }
|
84
|
+
|
85
|
+
let(:standalone_shirts) do
|
86
|
+
2.times.map {
|
87
|
+
create(:inventory_unit,
|
88
|
+
variant: shirt,
|
89
|
+
line_item: standalone_line_item,
|
90
|
+
state: :on_hand)
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
let(:shipment) { create(:shipment) }
|
95
|
+
|
96
|
+
before do
|
97
|
+
shipment.inventory_units << assembly_shirts
|
98
|
+
shipment.inventory_units << standalone_shirts
|
99
|
+
end
|
100
|
+
|
101
|
+
it "set states numbers properly for all items" do
|
102
|
+
shipment.manifest.each do |item|
|
103
|
+
if item.line_item.id == standalone_line_item.id
|
104
|
+
expect(item.states["on_hand"]).to eq standalone_shirts.count
|
105
|
+
else
|
106
|
+
expect(item.states["on_hand"]).to eq assembly_shirts.count
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|