solidus_product_assembly 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/dependabot.yml +7 -0
  5. data/.github/stale.yml +17 -0
  6. data/.gitignore +14 -2
  7. data/.rspec +2 -2
  8. data/.rubocop.yml +4 -0
  9. data/.rubocop_todo.yml +192 -0
  10. data/CHANGELOG.md +19 -0
  11. data/Gemfile +21 -9
  12. data/LICENSE +26 -0
  13. data/README.md +52 -18
  14. data/Rakefile +4 -19
  15. data/app/controllers/spree/admin/parts_controller.rb +13 -11
  16. data/app/decorators/controllers/solidus_product_assembly/spree/checkout_controller_decorator.rb +13 -0
  17. data/app/decorators/helpers/solidus_product_assembly/spree/admin/orders_helper_decorator.rb +19 -0
  18. data/app/decorators/models/solidus_product_assembly/spree/inventory_unit_decorator.rb +19 -0
  19. data/app/decorators/models/solidus_product_assembly/spree/line_item_decorator.rb +52 -0
  20. data/app/decorators/models/solidus_product_assembly/spree/product_decorator.rb +70 -0
  21. data/app/decorators/models/solidus_product_assembly/spree/return_item_decorator.rb +15 -0
  22. data/app/decorators/models/solidus_product_assembly/spree/shipment_decorator.rb +55 -0
  23. data/app/decorators/models/solidus_product_assembly/spree/stock/availability_validator_decorator.rb +37 -0
  24. data/app/decorators/models/solidus_product_assembly/spree/stock/inventory_unit_builder_decorator.rb +39 -0
  25. data/app/decorators/models/solidus_product_assembly/spree/stock/inventory_units_finalizer_decorator.rb +33 -0
  26. data/app/decorators/models/solidus_product_assembly/spree/stock/inventory_validator_decorator.rb +22 -0
  27. data/app/decorators/models/solidus_product_assembly/spree/variant_decorator.rb +26 -0
  28. data/app/models/spree/assemblies_part.rb +6 -4
  29. data/app/models/spree/calculator/returns/assemblies_default_refund_amount.rb +17 -0
  30. data/app/models/spree/order_inventory_assembly.rb +11 -2
  31. data/app/overrides/add_admin_product_form_fields.rb +7 -5
  32. data/app/overrides/add_admin_tabs.rb +7 -5
  33. data/app/overrides/add_line_item_description.rb +7 -5
  34. data/app/overrides/spree/admin/orders/_carton_manifest/_assembly_parts_price.html.erb.deface +9 -0
  35. data/app/overrides/spree/admin/orders/_carton_manifest/_assembly_parts_total_price.html.erb.deface +9 -0
  36. data/app/overrides/spree/admin/orders/_shipment/stock_contents.html.erb.deface +7 -1
  37. data/app/overrides/spree/products/show/add_links_to_parts.html.erb.deface +2 -2
  38. data/app/views/spree/admin/orders/_assemblies.html.erb +8 -17
  39. data/app/views/spree/admin/orders/_stock_contents.html.erb +2 -62
  40. data/app/views/spree/admin/orders/_stock_contents_2_3.html.erb +69 -0
  41. data/app/views/spree/admin/orders/_stock_contents_2_4.html.erb +70 -0
  42. data/app/views/spree/admin/orders/_stock_item.html.erb +13 -10
  43. data/app/views/spree/admin/parts/_parts_table.html.erb +17 -11
  44. data/app/views/spree/admin/parts/available.html.erb +10 -8
  45. data/app/views/spree/admin/parts/available.js.erb +9 -7
  46. data/app/views/spree/admin/parts/index.html.erb +1 -1
  47. data/app/views/spree/admin/products/_product_assembly_fields.html.erb +2 -2
  48. data/app/views/spree/admin/shared/_product_assembly_product_tabs.html.erb +1 -1
  49. data/app/views/spree/api/line_items/show.v1.rabl +27 -0
  50. data/app/views/spree/checkout/_line_item_manifest.html.erb +3 -1
  51. data/bin/console +17 -0
  52. data/bin/rails +12 -4
  53. data/bin/setup +8 -0
  54. data/config/routes.rb +2 -2
  55. data/db/migrate/20091028152124_add_many_to_many_relation_to_products.rb +7 -5
  56. data/db/migrate/20091029165620_add_parts_fields_to_products.rb +18 -16
  57. data/db/migrate/20120316141830_namespace_product_assembly_for_spree_one.rb +3 -1
  58. data/db/migrate/20140620223938_add_id_to_spree_assemblies_parts.rb +4 -2
  59. data/lib/generators/solidus_product_assembly/install/install_generator.rb +13 -8
  60. data/lib/solidus_product_assembly/engine.rb +11 -8
  61. data/lib/solidus_product_assembly/testing_support/factories.rb +4 -0
  62. data/lib/solidus_product_assembly/version.rb +3 -1
  63. data/lib/solidus_product_assembly.rb +5 -1
  64. data/lib/tasks/spree2_upgrade.rake +12 -12
  65. data/solidus_product_assembly.gemspec +25 -20
  66. data/spec/features/admin/orders_spec.rb +114 -16
  67. data/spec/features/admin/parts_spec.rb +5 -3
  68. data/spec/features/admin/return_items_spec.rb +151 -0
  69. data/spec/features/checkout_spec.rb +103 -21
  70. data/spec/models/spree/assemblies_part_spec.rb +3 -1
  71. data/spec/models/spree/inventory_unit_spec.rb +15 -6
  72. data/spec/models/spree/line_item_spec.rb +6 -4
  73. data/spec/models/spree/order_contents_spec.rb +6 -5
  74. data/spec/models/spree/order_inventory_assembly_spec.rb +8 -6
  75. data/spec/models/spree/order_inventory_spec.rb +7 -3
  76. data/spec/models/spree/product_spec.rb +15 -14
  77. data/spec/models/spree/shipment_spec.rb +20 -13
  78. data/spec/models/spree/stock/availability_validator_spec.rb +22 -33
  79. data/spec/models/spree/stock/coordinator_spec.rb +11 -3
  80. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +5 -7
  81. data/spec/models/spree/variant_spec.rb +3 -1
  82. data/spec/spec_helper.rb +18 -47
  83. data/spec/support/shared_contexts/order_with_bundle.rb +2 -0
  84. metadata +80 -102
  85. data/.travis.yml +0 -21
  86. data/LICENSE.md +0 -13
  87. data/app/controllers/spree/checkout_controller_decorator.rb +0 -9
  88. data/app/helpers/spree/admin/orders_helper_decorator.rb +0 -9
  89. data/app/models/spree/inventory_unit_decorator.rb +0 -13
  90. data/app/models/spree/line_item_decorator.rb +0 -44
  91. data/app/models/spree/product_decorator.rb +0 -56
  92. data/app/models/spree/shipment_decorator.rb +0 -50
  93. data/app/models/spree/stock/availability_validator.rb +0 -28
  94. data/app/models/spree/stock/inventory_unit_builder_decorator.rb +0 -30
  95. data/app/models/spree/stock/inventory_validator_decorator.rb +0 -12
  96. data/app/models/spree/variant_decorator.rb +0 -13
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module LineItemDecorator
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ scope :assemblies, -> { joins(product: :parts).distinct }
9
+ end
10
+ end
11
+
12
+ def any_units_shipped?
13
+ inventory_units.any?(&:shipped?)
14
+ end
15
+
16
+ # The parts that apply to this particular LineItem. Usually `product#parts`, but
17
+ # provided as a hook if you want to override and customize the parts for a specific
18
+ # LineItem.
19
+ delegate :parts, to: :product
20
+
21
+ # The number of the specified variant that make up this LineItem. By default, calls
22
+ # `product#count_of`, but provided as a hook if you want to override and customize
23
+ # the parts available for a specific LineItem. Note that if you only customize whether
24
+ # a variant is included in the LineItem, and don't customize the quantity of that part
25
+ # per LineItem, you shouldn't need to override this method.
26
+ delegate :count_of, to: :product
27
+
28
+ def quantity_by_variant
29
+ if product.assembly?
30
+ {}.tap { |hash| product.assemblies_parts.each { |ap| hash[ap.part] = ap.count * quantity } }
31
+ else
32
+ { variant => quantity }
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def update_inventory
39
+ saved_changes = respond_to?(:saved_changes?) ? saved_changes? : changed?
40
+ if (saved_changes || target_shipment.present?) && order.has_checkout_step?("delivery")
41
+ if product.assembly?
42
+ ::Spree::OrderInventoryAssembly.new(self).verify(target_shipment)
43
+ else
44
+ ::Spree::OrderInventory.new(order, self).verify(target_shipment)
45
+ end
46
+ end
47
+ end
48
+
49
+ ::Spree::LineItem.prepend self
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module ProductDecorator
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ has_and_belongs_to_many :parts, class_name: "Spree::Variant",
9
+ join_table: "spree_assemblies_parts",
10
+ foreign_key: "assembly_id", association_foreign_key: "part_id"
11
+
12
+ has_many :assemblies_parts, class_name: "Spree::AssembliesPart",
13
+ foreign_key: "assembly_id"
14
+
15
+ scope :individual_saled, -> { where(individual_sale: true) }
16
+
17
+ scope :search_can_be_part, ->(query){
18
+ not_deleted.available.joins(:master)
19
+ .where(arel_table["name"].matches("%#{query}%").or(::Spree::Variant.arel_table["sku"].matches("%#{query}%")))
20
+ .where(can_be_part: true)
21
+ .limit(30)
22
+ }
23
+
24
+ validate :assembly_cannot_be_part, if: :assembly?
25
+ end
26
+ end
27
+
28
+ def add_part(variant, count = 1)
29
+ set_part_count(variant, count_of(variant) + count)
30
+ end
31
+
32
+ def remove_part(variant)
33
+ set_part_count(variant, 0)
34
+ end
35
+
36
+ def set_part_count(variant, count)
37
+ ap = assemblies_part(variant)
38
+ if count > 0
39
+ ap.count = count
40
+ ap.save
41
+ else
42
+ ap.destroy
43
+ end
44
+ reload
45
+ end
46
+
47
+ def assembly?
48
+ parts.present?
49
+ end
50
+
51
+ def count_of(variant)
52
+ ap = assemblies_part(variant)
53
+ # This checks persisted because the default count is 1
54
+ ap.persisted? ? ap.count : 0
55
+ end
56
+
57
+ def assembly_cannot_be_part
58
+ errors.add(:can_be_part, I18n.t('spree.assembly_cannot_be_part')) if can_be_part
59
+ end
60
+
61
+ private
62
+
63
+ def assemblies_part(variant)
64
+ ::Spree::AssembliesPart.get(id, variant.id)
65
+ end
66
+
67
+ ::Spree::Product.prepend self
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module ReturnItemDecorator
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ self.refund_amount_calculator = ::Spree::Calculator::Returns::AssembliesDefaultRefundAmount
9
+ end
10
+ end
11
+
12
+ ::Spree::ReturnItem.prepend self
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module ShipmentDecorator
6
+ # Overriden from Spree core as a product bundle part should not be put
7
+ # together with an individual product purchased (even though they're the
8
+ # very same variant) That is so we can tell the store admin which units
9
+ # were purchased individually and which ones as parts of the bundle
10
+ #
11
+ # Account for situations where we can't track the line_item for a variant.
12
+ # This should avoid exceptions when users upgrade from spree 1.3
13
+ #
14
+ # TODO Can possibly be removed as well. We already override the manifest
15
+ # partial so we can get the product there
16
+ def manifest
17
+ items = []
18
+ inventory_units.joins(:variant).includes(:variant, :line_item).group_by(&:variant).each do |variant, units|
19
+ units.group_by(&:line_item).each do |line_item, units|
20
+ states = {}
21
+ units.group_by(&:state).each { |state, iu| states[state] = iu.count }
22
+ line_item ||= order.find_line_item_by_variant(variant)
23
+
24
+ part = line_item ? line_item.product.assembly? : false
25
+ items << OpenStruct.new(part: part,
26
+ product: line_item.try(:product),
27
+ line_item: line_item,
28
+ variant: variant,
29
+ quantity: units.length,
30
+ states: states)
31
+ end
32
+ end
33
+ items
34
+ end
35
+
36
+ # There might be scenarios where we don't want to display every single
37
+ # variant on the shipment. e.g. when ordering a product bundle that includes
38
+ # 5 other parts. Frontend users should only see the product bundle as a
39
+ # single item to ship
40
+ def line_item_manifest
41
+ inventory_units.includes(:line_item, :variant).group_by(&:line_item).map do |line_item, units|
42
+ states = {}
43
+ units.group_by(&:state).each { |state, iu| states[state] = iu.count }
44
+ OpenStruct.new(line_item: line_item, variant: line_item.variant, quantity: units.length, states: states)
45
+ end
46
+ end
47
+
48
+ def inventory_units_for_item(line_item, variant)
49
+ inventory_units.where(line_item_id: line_item.id, variant_id: variant.id)
50
+ end
51
+
52
+ ::Spree::Shipment.prepend self
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module Stock
6
+ # Overridden from spree core to make it also check for assembly parts stock
7
+ module AvailabilityValidatorDecorator
8
+ def validate(line_item)
9
+ if line_item.product.assembly?
10
+ line_item.quantity_by_variant.each do |variant, variant_quantity|
11
+ inventory_units = line_item.inventory_units.where(variant: variant).count
12
+ quantity = variant_quantity - inventory_units
13
+ next if quantity <= 0
14
+ next unless variant
15
+
16
+ quantifier = ::Spree::Stock::Quantifier.new(variant)
17
+
18
+ next if quantifier.can_supply? quantity
19
+
20
+ display_name = variant.name.to_s
21
+ display_name += %{ (#{variant.options_text})} if variant.options_text.present?
22
+
23
+ line_item.errors[:quantity] << I18n.t(
24
+ 'spree.selected_quantity_not_available',
25
+ item: display_name.inspect
26
+ )
27
+ end
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ ::Spree::Stock::AvailabilityValidator.prepend self
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module Stock
6
+ module InventoryUnitBuilderDecorator
7
+ def units
8
+ @order.line_items.flat_map do |line_item|
9
+ line_item.quantity_by_variant.flat_map do |variant, quantity|
10
+ quantity.times.map { build_inventory_unit(variant, line_item) }
11
+ end
12
+ end
13
+ end
14
+
15
+ def build_inventory_unit(variant, line_item)
16
+ inventory_unit_attributes = {
17
+ pending: true,
18
+ variant: variant,
19
+ line_item: line_item,
20
+ }
21
+ if ::Spree.solidus_gem_version < Gem::Version.new('2.5.x')
22
+ inventory_unit_attributes[:order] = @order
23
+ end
24
+ @order.inventory_units.includes(
25
+ variant: {
26
+ product: {
27
+ shipping_category: {
28
+ shipping_methods: [:calculator, { zones: :zone_members }]
29
+ }
30
+ }
31
+ }
32
+ ).build(inventory_unit_attributes)
33
+ end
34
+
35
+ ::Spree::Stock::InventoryUnitBuilder.prepend self
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module Stock
6
+ module InventoryUnitsFinalizerDecorator
7
+ private
8
+
9
+ def unstock_inventory_units
10
+ inventory_units.group_by(&:shipment_id).each_value do |inventory_units_for_shipment|
11
+ inventory_units_for_shipment.group_by(&:line_item_id).each_value do |units|
12
+ shipment = units.first.shipment
13
+ line_item = units.first.line_item
14
+
15
+ if line_item.product.assembly?
16
+ units.group_by(&:variant_id).each_value do |units_for_part|
17
+ part = units_for_part.first.variant
18
+ shipment.stock_location.unstock part, units_for_part.count, shipment
19
+ end
20
+ else
21
+ shipment.stock_location.unstock line_item.variant, units.count, shipment
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ if ::Spree.solidus_gem_version >= Gem::Version.new('2.8')
28
+ ::Spree::Stock::InventoryUnitsFinalizer.prepend self
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module Stock
6
+ module InventoryValidatorDecorator
7
+ def validate(line_item)
8
+ total_quantity = line_item.quantity_by_variant.values.sum
9
+
10
+ if line_item.inventory_units.count != total_quantity
11
+ line_item.errors[:inventory] << I18n.t(
12
+ 'spree.inventory_not_available',
13
+ item: line_item.variant.name
14
+ )
15
+ end
16
+ end
17
+
18
+ ::Spree::Stock::InventoryValidator.prepend self
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusProductAssembly
4
+ module Spree
5
+ module VariantDecorator
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ has_and_belongs_to_many :assemblies,
9
+ class_name: "Spree::Product",
10
+ join_table: "spree_assemblies_parts",
11
+ foreign_key: "part_id", association_foreign_key: "assembly_id"
12
+ end
13
+ end
14
+
15
+ def assemblies_for(products)
16
+ assemblies.where(id: products)
17
+ end
18
+
19
+ def part?
20
+ assemblies.exists?
21
+ end
22
+
23
+ ::Spree::Variant.prepend self
24
+ end
25
+ end
26
+ end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Spree
2
- class AssembliesPart < ActiveRecord::Base
3
- belongs_to :assembly, :class_name => "Spree::Product",
4
- :foreign_key => "assembly_id", touch: true
4
+ class AssembliesPart < ApplicationRecord
5
+ belongs_to :assembly, class_name: "Spree::Product",
6
+ foreign_key: "assembly_id", touch: true
5
7
 
6
- belongs_to :part, :class_name => "Spree::Variant", :foreign_key => "part_id"
8
+ belongs_to :part, class_name: "Spree::Variant", foreign_key: "part_id"
7
9
 
8
10
  def self.get(assembly_id, part_id)
9
11
  find_or_initialize_by(assembly_id: assembly_id, part_id: part_id)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Calculator::Returns
5
+ class AssembliesDefaultRefundAmount < DefaultRefundAmount
6
+ def compute(return_item)
7
+ percentage = return_item.inventory_unit.percentage_of_line_item
8
+ if percentage < 1 && return_item.variant.part?
9
+ line_item = return_item.inventory_unit.line_item
10
+ (super * percentage * line_item.quantity).round 4, :up
11
+ else
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Spree
2
4
  # This class has basically the same functionality of Spree core OrderInventory
3
5
  # except that it takes account of bundle parts and properly creates and removes
@@ -19,8 +21,14 @@ module Spree
19
21
  self.variant = part
20
22
 
21
23
  if existing_parts < total_parts
22
- shipment = determine_target_shipment unless shipment
23
- add_to_shipment(shipment, total_parts - existing_parts)
24
+ if method(:determine_target_shipment).arity == 1
25
+ quantity = total_parts - existing_parts
26
+ shipment = determine_target_shipment(quantity) unless shipment
27
+ add_to_shipment(shipment, quantity)
28
+ else
29
+ shipment = determine_target_shipment unless shipment
30
+ add_to_shipment(shipment, total_parts - existing_parts)
31
+ end
24
32
  elsif existing_parts > total_parts
25
33
  quantity = existing_parts - total_parts
26
34
  if shipment.present?
@@ -28,6 +36,7 @@ module Spree
28
36
  else
29
37
  order.shipments.each do |shipment|
30
38
  break if quantity == 0
39
+
31
40
  quantity -= remove_from_shipment(shipment, quantity)
32
41
  end
33
42
  end
@@ -1,5 +1,7 @@
1
- Deface::Override.new(:virtual_path => "spree/admin/products/_form",
2
- :name => "product_assembly_admin_product_form_right",
3
- :insert_after => "[data-hook='admin_product_form_right'], #admin_product_form_right[data-hook]",
4
- :partial => "spree/admin/products/product_assembly_fields",
5
- :disabled => false)
1
+ # frozen_string_literal: true
2
+
3
+ Deface::Override.new(virtual_path: "spree/admin/products/_form",
4
+ name: "product_assembly_admin_product_form_right",
5
+ insert_after: "[data-hook='admin_product_form_right'], #admin_product_form_right[data-hook]",
6
+ partial: "spree/admin/products/product_assembly_fields",
7
+ disabled: false)
@@ -1,5 +1,7 @@
1
- Deface::Override.new(:virtual_path => "spree/admin/shared/_product_tabs",
2
- :name => "product_assembly_admin_product_tabs",
3
- :insert_bottom => "[data-hook='admin_product_tabs']",
4
- :partial => "spree/admin/shared/product_assembly_product_tabs",
5
- :disabled => false)
1
+ # frozen_string_literal: true
2
+
3
+ Deface::Override.new(virtual_path: "spree/admin/shared/_product_tabs",
4
+ name: "product_assembly_admin_product_tabs",
5
+ insert_bottom: "[data-hook='admin_product_tabs']",
6
+ partial: "spree/admin/shared/product_assembly_product_tabs",
7
+ disabled: false)
@@ -1,5 +1,7 @@
1
- Deface::Override.new(:virtual_path => "spree/orders/_line_item",
2
- :name => "product_assembly_cart_item_description",
3
- :insert_bottom => "[data-hook='cart_item_description']",
4
- :partial => "spree/orders/cart_description",
5
- :disabled => false)
1
+ # frozen_string_literal: true
2
+
3
+ Deface::Override.new(virtual_path: "spree/orders/_line_item",
4
+ name: "product_assembly_cart_item_description",
5
+ insert_bottom: "[data-hook='cart_item_description']",
6
+ partial: "spree/orders/cart_description",
7
+ disabled: false)
@@ -0,0 +1,9 @@
1
+ <!-- replace ".item-price" -->
2
+
3
+ <% if item.variant.part? %>
4
+ <td class="item-price">---</td>
5
+ <% else %>
6
+ <td class="item-price">
7
+ <%= line_item_shipment_price(item.line_item, item.quantity) %>
8
+ </td>
9
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <!-- replace ".item-total" -->
2
+
3
+ <% if item.variant.part? %>
4
+ <td class="item-total align-center">---</td>
5
+ <% else %>
6
+ <td class="item-total align-center">
7
+ <%= line_item_shipment_price(item.line_item, item.quantity) %>
8
+ </td>
9
+ <% end %>
@@ -1,2 +1,8 @@
1
1
  <!-- replace_contents '.stock-contents tbody' -->
2
- <%= render 'stock_contents', shipment: shipment %>
2
+ <% if Spree.solidus_gem_version < Gem::Version.new('2.4') %>
3
+ <%= render "stock_contents_2_3", shipment: shipment %>
4
+ <% elsif Spree.solidus_gem_version < Gem::Version.new('2.5') %>
5
+ <%= render "stock_contents_2_4", shipment: shipment %>
6
+ <% else %>
7
+ <%= render "stock_contents", shipment: shipment %>
8
+ <% end %>
@@ -1,14 +1,14 @@
1
1
  <!-- insert_after '#cart-form' -->
2
2
  <% if @product.parts.any?(&:in_stock?) %>
3
3
 
4
- <h6><%= Spree.t(:parts_included) %></h6>
4
+ <h6><%= t('spree.parts_included') %></h6>
5
5
 
6
6
  <ul id="products" class="inline product-listing" data-hook>
7
7
  <% @product.parts.each do |variant| %>
8
8
  <% if variant.in_stock? %>
9
9
  <li id="product_<%= variant.product.id %>" class="columns three <%= cycle("alpha", "secondary", "", "omega secondary") %>" data-hook="products_list_item" itemscope itemtype="http://schema.org/Product">
10
10
  <div class="product-image">
11
- <%= link_to small_image(variant.product, :itemprop => "name"), variant.product %>
11
+ <%= render 'spree/shared/image', image: variant.product.gallery.images.first, size: :small %>
12
12
  </div>
13
13
  <%= link_to truncate(variant.product.name, :length => 50), variant.product, :class => 'info', :itemprop => "name", :title => variant.product.name %>
14
14
  <% if variant.product.individual_sale? %>
@@ -1,15 +1,16 @@
1
1
  <% if order.line_items.assemblies.any? %>
2
2
  <fieldset class="no-border-bottom">
3
3
  <legend align="center" class="" data-hook="">
4
- <%= Spree.t(:product_bundles) %>
4
+ <%= t('spree.product_bundles') %>
5
5
  </legend>
6
6
  </fieldset>
7
7
 
8
8
  <table class="product-bundles index" data-hook="line-items">
9
9
  <colgroup>
10
- <col style="width: 10%;" />
11
- <col style="width: 20%;" />
12
- <col style="width: 20%;" />
10
+ <col style="width: 15%;" />
11
+ <col style="width: 40%;" />
12
+ <col style="width: 15%;" />
13
+ <col style="width: 15%;" />
13
14
  <col style="width: 15%;" />
14
15
  </colgroup>
15
16
 
@@ -19,14 +20,15 @@
19
20
  <th><%= Spree::LineItem.human_attribute_name(:price) %></th>
20
21
  <th><%= Spree::LineItem.human_attribute_name(:quantity) %></th>
21
22
  <th><%= Spree::LineItem.human_attribute_name(:total) %></th>
22
- <th class="orders-actions actions" data-hook="admin_order_form_line_items_header_actions">&nbsp;</th>
23
23
  </tr>
24
24
  </thead>
25
25
 
26
26
  <tbody>
27
27
  <% order.line_items.assemblies.each do |item| %>
28
28
  <%= content_tag :tr, class: 'line-item', id: "line-item-#{item.id}", data: { line_item_id: item.id } do %>
29
- <td class="line-item-image"><%= image_tag item.variant.display_image.attachment(:mini) %></td>
29
+ <td class="line-item-image"><%= render 'spree/shared/image',
30
+ image: (item.variant.gallery.images.first || item.variant.product.gallery.images.first),
31
+ size: :mini %></td>
30
32
  <td class="line-item-name">
31
33
  <%= item.variant.product.name %><br><%= "(" + variant_options(item.variant) + ")" unless item.variant.option_values.empty? %>
32
34
  <% if item.variant.sku.present? %>
@@ -37,18 +39,7 @@
37
39
  <td class="line-item-qty-show align-center">
38
40
  <%= item.quantity %>
39
41
  </td>
40
- <td class="line-item-qty-edit">
41
- <%= number_field_tag :quantity, item.quantity, :min => 0, :class => "line_item_quantity", :size => 5 %>
42
- </td>
43
42
  <td class="line-item-total align-center"><%= line_item_shipment_price(item, item.quantity) %></td>
44
- <td class="cart-line-item-delete actions" data-hook="cart_line_item_delete">
45
- <% if can? :update, item %>
46
- <%= link_to '', '#', :class => 'save-line-item fa fa-ok no-text with-tip', :title => Spree.t('actions.save') %>
47
- <%= link_to '', '#', :class => 'cancel-line-item fa fa-cancel no-text with-tip', :title => Spree.t('actions.cancel') %>
48
- <%= link_to '', '#', :class => 'edit-line-item fa fa-edit no-text with-tip', :title => Spree.t('actions.edit') %>
49
- <%= link_to '', '#', :class => 'delete-line-item fa fa-trash no-text with-tip', :title => Spree.t('actions.delete') %>
50
- <% end %>
51
- </td>
52
43
  <% end %>
53
44
  <% end %>
54
45
  </tbody>
@@ -1,69 +1,9 @@
1
1
  <%= render 'stock_item', shipment: shipment %>
2
2
 
3
3
  <% unless shipment.shipped? %>
4
- <tr class="edit-method hidden total">
5
- <td colspan="5">
6
- <div class="field alpha five columns">
7
- <%= label_tag 'selected_shipping_rate_id', Spree.t(:shipping_method) %>
8
- <%= select_tag :selected_shipping_rate_id,
9
- options_for_select(shipment.shipping_rates.map {|sr| ["#{sr.name} #{sr.display_price}", sr.id] }, shipment.selected_shipping_rate_id),
10
- {:class => 'select2 fullwidth', :data => {'shipment-number' => shipment.number } } %>
11
- </div>
12
- </td>
13
- <td class="actions">
14
- <% if can? :update, shipment %>
15
- <%= link_to '', '#', :class => 'save-method fa fa-ok no-text with-tip',
16
- :data => {'shipment-number' => shipment.number, :action => 'save'}, title: Spree.t('actions.save') %>
17
- <%= link_to '', '#', :class => 'cancel-method fa fa-cancel no-text with-tip',
18
- :data => {:action => 'cancel'}, :title => Spree.t('actions.cancel') %>
19
- <% end %>
20
- </td>
4
+ <tr class="edit-shipping-method vertical-middle">
21
5
  </tr>
22
6
  <% end %>
23
7
 
24
- <tr class="show-method total">
25
- <% if shipment.shipping_method %>
26
- <td colspan="4">
27
- <strong><%= shipment.shipping_method.name %></strong>
28
- </td>
29
- <td class="total" align="center">
30
- <span><%= shipment.display_cost %></span>
31
- </td>
32
- <% else %>
33
- <td colspan='5'><%= Spree.t(:no_shipping_method_selected) %></td>
34
- <% end %>
35
-
36
- <td class="actions">
37
- <% if can? :update, shipment %>
38
- <%= link_to '', '#', :class => 'edit-method fa fa-edit no-text with-tip', :data => {:action => 'edit'}, :title => Spree.t('edit') %>
39
- <% end %>
40
- </td>
41
- </tr>
42
-
43
- <tr class="edit-tracking hidden total">
44
- <td colspan="5">
45
- <label><%= Spree.t(:tracking_number) %>:</label>
46
- <%= text_field_tag :tracking, shipment.tracking %>
47
- </td>
48
- <td class="actions">
49
- <% if can? :update, shipment %>
50
- <%= link_to '', '#', :class => 'save-tracking fa fa-ok no-text with-tip', :data => {'shipment-number' => shipment.number, :action => 'save'}, :title => Spree.t('actions.save') %>
51
- <%= link_to '', '#', :class => 'cancel-tracking fa fa-cancel no-text with-tip', :data => {:action => 'cancel'}, :title => Spree.t('actions.cancel') %>
52
- <% end %>
53
- </td>
54
- </tr>
55
-
56
- <tr class="show-tracking total">
57
- <td colspan="5">
58
- <% if shipment.tracking.present? %>
59
- <strong><%= Spree.t(:tracking) %>:</strong> <%= shipment.tracking %>
60
- <% else %>
61
- <%= Spree.t(:no_tracking_present) %>
62
- <% end %>
63
- </td>
64
- <td class="actions">
65
- <% if can? :update, shipment %>
66
- <%= link_to '', '#', :class => 'edit-tracking fa fa-edit no-text with-tip', :data => {:action => 'edit'}, :title => Spree.t('edit') %>
67
- <% end %>
68
- </td>
8
+ <tr class="edit-tracking vertical-middle">
69
9
  </tr>