spree_core 3.6.6 → 3.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree.js +60 -0
  3. data/app/finders/spree/countries/find.rb +31 -0
  4. data/app/finders/spree/credit_cards/find.rb +12 -0
  5. data/app/finders/spree/line_items/find_by_variant.rb +13 -0
  6. data/app/finders/spree/orders/find_current.rb +34 -0
  7. data/app/finders/spree/products/find.rb +93 -0
  8. data/app/finders/spree/taxons/find.rb +79 -0
  9. data/app/helpers/spree/base_helper.rb +7 -3
  10. data/app/helpers/spree/products_helper.rb +2 -1
  11. data/app/models/concerns/spree/adjustment_source.rb +11 -6
  12. data/app/models/concerns/spree/user_address.rb +2 -2
  13. data/app/models/concerns/spree/vat_price_calculation.rb +2 -1
  14. data/app/models/spree/ability.rb +2 -2
  15. data/app/models/spree/address.rb +23 -14
  16. data/app/models/spree/adjustable/adjustments_updater.rb +1 -1
  17. data/app/models/spree/adjustable/promotion_accumulator.rb +2 -1
  18. data/app/models/spree/adjustment.rb +18 -3
  19. data/app/models/spree/asset/support/active_storage.rb +1 -1
  20. data/app/models/spree/calculator.rb +1 -4
  21. data/app/models/spree/calculator/flexi_rate.rb +8 -11
  22. data/app/models/spree/calculator/returns/default_refund_amount.rb +3 -1
  23. data/app/models/spree/calculator/shipping/flexi_rate.rb +13 -13
  24. data/app/models/spree/country.rb +4 -0
  25. data/app/models/spree/credit_card.rb +8 -2
  26. data/app/models/spree/customer_return.rb +1 -0
  27. data/app/models/spree/fulfilment_changer.rb +117 -0
  28. data/app/models/spree/gateway.rb +1 -0
  29. data/app/models/spree/gateway/bogus.rb +3 -2
  30. data/app/models/spree/image.rb +13 -0
  31. data/app/models/spree/image/configuration/active_storage.rb +3 -3
  32. data/app/models/spree/inventory_unit.rb +1 -1
  33. data/app/models/spree/line_item.rb +3 -2
  34. data/app/models/spree/order.rb +72 -28
  35. data/app/models/spree/order/checkout.rb +10 -0
  36. data/app/models/spree/order/store_credit.rb +14 -35
  37. data/app/models/spree/order_contents.rb +22 -118
  38. data/app/models/spree/order_inventory.rb +6 -2
  39. data/app/models/spree/order_merger.rb +1 -3
  40. data/app/models/spree/order_promotion.rb +10 -0
  41. data/app/models/spree/order_updater.rb +11 -8
  42. data/app/models/spree/payment.rb +9 -3
  43. data/app/models/spree/payment/processing.rb +4 -4
  44. data/app/models/spree/preferences/store.rb +3 -3
  45. data/app/models/spree/product.rb +32 -0
  46. data/app/models/spree/product/scopes.rb +13 -34
  47. data/app/models/spree/product_property.rb +1 -1
  48. data/app/models/spree/promotion.rb +2 -0
  49. data/app/models/spree/promotion/actions/create_adjustment.rb +6 -1
  50. data/app/models/spree/promotion/actions/create_item_adjustments.rb +10 -2
  51. data/app/models/spree/promotion/actions/create_line_items.rb +3 -2
  52. data/app/models/spree/promotion/actions/free_shipping.rb +1 -0
  53. data/app/models/spree/promotion/rules/item_total.rb +2 -2
  54. data/app/models/spree/promotion_handler/coupon.rb +10 -6
  55. data/app/models/spree/promotion_handler/page.rb +1 -1
  56. data/app/models/spree/promotion_handler/promotion_duplicator.rb +4 -4
  57. data/app/models/spree/refund.rb +1 -1
  58. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -0
  59. data/app/models/spree/reimbursement_tax_calculator.rb +2 -2
  60. data/app/models/spree/return_item.rb +7 -4
  61. data/app/models/spree/return_item/eligibility_validator/default.rb +6 -6
  62. data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +1 -1
  63. data/app/models/spree/shipment.rb +27 -34
  64. data/app/models/spree/shipping_method.rb +2 -0
  65. data/app/models/spree/shipping_rate.rb +31 -16
  66. data/app/models/spree/stock/adjuster.rb +1 -0
  67. data/app/models/spree/stock/estimator.rb +2 -0
  68. data/app/models/spree/stock/inventory_unit_builder.rb +5 -5
  69. data/app/models/spree/stock/packer.rb +1 -0
  70. data/app/models/spree/stock/quantifier.rb +16 -4
  71. data/app/models/spree/stock_item.rb +1 -0
  72. data/app/models/spree/stock_location.rb +1 -1
  73. data/app/models/spree/stock_movement.rb +1 -0
  74. data/app/models/spree/stock_transfer.rb +1 -1
  75. data/app/models/spree/store_credit.rb +5 -10
  76. data/app/models/spree/tax_rate.rb +3 -0
  77. data/app/models/spree/taxon.rb +2 -2
  78. data/app/models/spree/taxon_image.rb +18 -0
  79. data/app/models/spree/{taxon_icon → taxon_image}/configuration/active_storage.rb +2 -2
  80. data/app/models/spree/{taxon_icon → taxon_image}/configuration/paperclip.rb +1 -1
  81. data/app/models/spree/variant.rb +28 -2
  82. data/app/models/spree/zone.rb +5 -5
  83. data/app/paginators/spree/shared/paginate.rb +19 -0
  84. data/app/services/spree/cart/add_item.rb +43 -0
  85. data/app/services/spree/cart/create.rb +21 -0
  86. data/app/services/spree/cart/recalculate.rb +32 -0
  87. data/app/services/spree/cart/remove_item.rb +37 -0
  88. data/app/services/spree/cart/remove_line_item.rb +16 -0
  89. data/app/services/spree/cart/set_quantity.rb +22 -0
  90. data/app/services/spree/cart/update.rb +37 -0
  91. data/app/services/spree/checkout/add_store_credit.rb +51 -0
  92. data/app/services/spree/checkout/advance.rb +18 -0
  93. data/app/services/spree/checkout/complete.rb +23 -0
  94. data/app/services/spree/checkout/get_shipping_rates.rb +48 -0
  95. data/app/services/spree/checkout/next.rb +13 -0
  96. data/app/services/spree/checkout/remove_store_credit.rb +17 -0
  97. data/app/services/spree/checkout/update.rb +13 -0
  98. data/app/services/spree/compare_line_items.rb +21 -0
  99. data/app/services/spree/generate_token.rb +20 -0
  100. data/app/sorters/spree/products/sort.rb +58 -0
  101. data/config/locales/en.yml +20 -1
  102. data/db/default/spree/countries.rb +1 -1
  103. data/db/default/spree/default_reimbursement_type.rb +1 -1
  104. data/db/default/spree/roles.rb +2 -2
  105. data/db/default/spree/states.rb +2 -1
  106. data/db/default/spree/stores.rb +1 -1
  107. data/db/default/spree/zones.rb +5 -6
  108. data/db/migrate/20120831092320_spree_one_two.rb +36 -36
  109. data/db/migrate/20120831092359_spree_promo_one_two.rb +1 -1
  110. data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
  111. data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
  112. data/db/migrate/20130301162924_create_shipping_method_categories.rb +1 -1
  113. data/db/migrate/20130304162240_create_spree_shipping_rates.rb +1 -1
  114. data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
  115. data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
  116. data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
  117. data/db/migrate/20140309023735_migrate_old_preferences.rb +5 -1
  118. data/db/migrate/20140309024355_create_spree_stores.rb +1 -1
  119. data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
  120. data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
  121. data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
  122. data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
  123. data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
  124. data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
  125. data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
  126. data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
  127. data/db/migrate/20150118210639_create_spree_store_credits.rb +1 -1
  128. data/db/migrate/20150118211500_create_spree_store_credit_categories.rb +1 -1
  129. data/db/migrate/20150118212051_create_spree_store_credit_events.rb +1 -1
  130. data/db/migrate/20150118212101_create_spree_store_credit_types.rb +1 -1
  131. data/db/migrate/20150309161154_ensure_payments_have_numbers.rb +6 -2
  132. data/db/migrate/20180613080857_rename_guest_token_to_token_in_orders.rb +5 -0
  133. data/db/migrate/20180915160001_add_timestamps_to_spree_prices.rb +12 -0
  134. data/db/migrate/20181024100754_add_deleted_at_to_spree_credit_cards.rb +6 -0
  135. data/lib/generators/spree/custom_user/custom_user_generator.rb +1 -3
  136. data/lib/generators/spree/dummy/dummy_generator.rb +30 -33
  137. data/lib/generators/spree/dummy/templates/rails/database.yml +6 -1
  138. data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
  139. data/lib/generators/spree/dummy_model/dummy_model_generator.rb +1 -1
  140. data/lib/generators/spree/install/install_generator.rb +2 -1
  141. data/lib/spree/core.rb +2 -4
  142. data/lib/spree/core/controller_helpers/auth.rb +15 -5
  143. data/lib/spree/core/controller_helpers/common.rb +0 -11
  144. data/lib/spree/core/controller_helpers/order.rb +6 -6
  145. data/lib/spree/core/controller_helpers/respond_with.rb +3 -1
  146. data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -0
  147. data/lib/spree/core/engine.rb +9 -3
  148. data/lib/spree/core/importer/order.rb +8 -12
  149. data/lib/spree/core/product_duplicator.rb +6 -1
  150. data/lib/spree/core/product_filters.rb +15 -14
  151. data/lib/spree/core/query_filters.rb +11 -0
  152. data/lib/spree/core/query_filters/comparable.rb +46 -0
  153. data/lib/spree/core/query_filters/date.rb +8 -0
  154. data/lib/spree/core/query_filters/number.rb +8 -0
  155. data/lib/spree/core/query_filters/text.rb +32 -0
  156. data/lib/spree/core/token_generator.rb +2 -2
  157. data/lib/spree/core/version.rb +1 -1
  158. data/lib/spree/i18n.rb +1 -1
  159. data/lib/spree/migrations.rb +2 -0
  160. data/lib/spree/money.rb +12 -12
  161. data/lib/spree/permitted_attributes.rb +11 -6
  162. data/lib/spree/service_module.rb +98 -0
  163. data/lib/spree/testing_support/capybara_config.rb +20 -0
  164. data/lib/spree/testing_support/capybara_ext.rb +6 -3
  165. data/lib/spree/testing_support/factories.rb +1 -1
  166. data/lib/spree/testing_support/factories/address_factory.rb +10 -9
  167. data/lib/spree/testing_support/factories/adjustment_factory.rb +8 -6
  168. data/lib/spree/testing_support/factories/country_factory.rb +4 -4
  169. data/lib/spree/testing_support/factories/credit_card_factory.rb +7 -5
  170. data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -1
  171. data/lib/spree/testing_support/factories/image_factory.rb +7 -1
  172. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +5 -4
  173. data/lib/spree/testing_support/factories/line_item_factory.rb +3 -2
  174. data/lib/spree/testing_support/factories/options_factory.rb +2 -3
  175. data/lib/spree/testing_support/factories/order_factory.rb +16 -12
  176. data/lib/spree/testing_support/factories/order_promotion_factory.rb +6 -0
  177. data/lib/spree/testing_support/factories/payment_factory.rb +9 -7
  178. data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -8
  179. data/lib/spree/testing_support/factories/price_factory.rb +2 -2
  180. data/lib/spree/testing_support/factories/product_factory.rb +10 -10
  181. data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -1
  182. data/lib/spree/testing_support/factories/promotion_factory.rb +14 -4
  183. data/lib/spree/testing_support/factories/property_factory.rb +2 -2
  184. data/lib/spree/testing_support/factories/prototype_factory.rb +3 -3
  185. data/lib/spree/testing_support/factories/refund_factory.rb +6 -6
  186. data/lib/spree/testing_support/factories/reimbursement_factory.rb +1 -1
  187. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +2 -2
  188. data/lib/spree/testing_support/factories/return_authorization_factory.rb +4 -3
  189. data/lib/spree/testing_support/factories/role_factory.rb +1 -1
  190. data/lib/spree/testing_support/factories/shipment_factory.rb +3 -3
  191. data/lib/spree/testing_support/factories/shipping_method_factory.rb +4 -4
  192. data/lib/spree/testing_support/factories/state_factory.rb +2 -5
  193. data/lib/spree/testing_support/factories/stock_factory.rb +3 -3
  194. data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
  195. data/lib/spree/testing_support/factories/stock_location_factory.rb +7 -7
  196. data/lib/spree/testing_support/factories/stock_movement_factory.rb +3 -3
  197. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
  198. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
  199. data/lib/spree/testing_support/factories/store_factory.rb +5 -4
  200. data/lib/spree/testing_support/factories/tax_rate_factory.rb +2 -1
  201. data/lib/spree/testing_support/factories/user_factory.rb +4 -4
  202. data/lib/spree/testing_support/factories/variant_factory.rb +15 -15
  203. data/lib/spree/testing_support/factories/zone_factory.rb +3 -3
  204. data/lib/spree/testing_support/image_helpers.rb +19 -0
  205. data/lib/tasks/core.rake +21 -4
  206. data/lib/tasks/exchanges.rake +4 -4
  207. data/spree_core.gemspec +3 -3
  208. data/vendor/assets/javascripts/fetch.umd.js +531 -0
  209. data/vendor/assets/javascripts/polyfill.min.js +1 -0
  210. metadata +50 -17
  211. data/app/assets/javascripts/spree.js.coffee +0 -59
  212. data/app/models/spree/taxon_icon.rb +0 -5
  213. data/lib/generators/spree/dummy/templates/initializers/custom_user.rb +0 -1
  214. data/lib/spree/core/environment.rb +0 -15
  215. data/lib/spree/core/environment/calculators.rb +0 -11
  216. data/lib/spree/core/environment_extension.rb +0 -28
  217. data/lib/spree/core/validators/email.rb +0 -8
  218. data/lib/spree/promo/environment.rb +0 -9
@@ -8,8 +8,9 @@ module Spree
8
8
  before_validation -> { self.calculator ||= Calculator::PercentOnLineItem.new }
9
9
 
10
10
  def perform(options = {})
11
- order = options[:order]
11
+ order = options[:order]
12
12
  promotion = options[:promotion]
13
+
13
14
  create_unique_adjustments(order, order.line_items) do |line_item|
14
15
  promotion.line_item_actionable?(order, line_item)
15
16
  end
@@ -17,7 +18,14 @@ module Spree
17
18
 
18
19
  def compute_amount(line_item)
19
20
  return 0 unless promotion.line_item_actionable?(line_item.order, line_item)
20
- [line_item.amount, compute(line_item)].min * -1
21
+
22
+ amounts = [line_item.amount, compute(line_item)]
23
+ order = line_item.order
24
+
25
+ # Prevent negative order totals
26
+ amounts << order.amount - order.adjustments.sum(:amount).abs if order.adjustments.any?
27
+
28
+ amounts.min * -1
21
29
  end
22
30
  end
23
31
  end
@@ -43,7 +43,7 @@ module Spree
43
43
  promotion_action_line_items.each do |item|
44
44
  current_quantity = order.quantity_of(item.variant)
45
45
  if current_quantity < item.quantity && item_available?(item)
46
- line_item = order.contents.add(item.variant, item.quantity - current_quantity)
46
+ line_item = Spree::Cart::AddItem.call(order: order, variant: item.variant, quantity: item.quantity - current_quantity).value
47
47
  action_taken = true if line_item.try(:valid?)
48
48
  end
49
49
  end
@@ -62,7 +62,8 @@ module Spree
62
62
  promotion_action_line_items.each do |item|
63
63
  line_item = order.find_line_item_by_variant(item.variant)
64
64
  next unless line_item.present?
65
- order.contents.remove(item.variant, (item.quantity || 1))
65
+
66
+ Spree::Cart::RemoveItem.call(order: order, variant: item.variant, quantity: (item.quantity || 1))
66
67
  action_taken = true
67
68
  end
68
69
 
@@ -6,6 +6,7 @@ module Spree
6
6
 
7
7
  def perform(payload = {})
8
8
  order = payload[:order]
9
+
9
10
  create_unique_adjustments(order, order.shipments)
10
11
  end
11
12
 
@@ -19,8 +19,8 @@ module Spree
19
19
  def eligible?(order, _options = {})
20
20
  item_total = order.item_total
21
21
 
22
- lower_limit_condition = item_total.send(preferred_operator_min == 'gte' ? :>= : :>, BigDecimal.new(preferred_amount_min.to_s))
23
- upper_limit_condition = item_total.send(preferred_operator_max == 'lte' ? :<= : :<, BigDecimal.new(preferred_amount_max.to_s))
22
+ lower_limit_condition = item_total.send(preferred_operator_min == 'gte' ? :>= : :>, BigDecimal(preferred_amount_min.to_s))
23
+ upper_limit_condition = item_total.send(preferred_operator_max == 'lte' ? :<= : :<, BigDecimal(preferred_amount_max.to_s))
24
24
 
25
25
  eligibility_errors.add(:base, ineligible_message_max) unless upper_limit_condition
26
26
  eligibility_errors.add(:base, ineligible_message_min) unless lower_limit_condition
@@ -17,6 +17,8 @@ module Spree
17
17
  else
18
18
  set_error_code :coupon_code_not_found
19
19
  end
20
+ else
21
+ set_error_code :coupon_code_not_found
20
22
  end
21
23
  self
22
24
  end
@@ -39,14 +41,14 @@ module Spree
39
41
  self
40
42
  end
41
43
 
42
- def set_success_code(c)
43
- @status_code = c
44
- @success = Spree.t(c)
44
+ def set_success_code(code)
45
+ @status_code = code
46
+ @success = Spree.t(code)
45
47
  end
46
48
 
47
- def set_error_code(c)
48
- @status_code = c
49
- @error = Spree.t(c)
49
+ def set_error_code(code)
50
+ @status_code = code
51
+ @error = Spree.t(code)
50
52
  end
51
53
 
52
54
  def promotion
@@ -73,6 +75,7 @@ module Spree
73
75
  Spree::PromotionActionLineItem.where(promotion_action: create_line_item_actions_ids).find_each do |item|
74
76
  line_item = order.find_line_item_by_variant(item.variant)
75
77
  next if line_item.blank?
78
+
76
79
  order.contents.remove(item.variant, item.quantity)
77
80
  end
78
81
  end
@@ -80,6 +83,7 @@ module Spree
80
83
  def handle_present_promotion
81
84
  return promotion_usage_limit_exceeded if promotion.usage_limit_exceeded?(order)
82
85
  return promotion_applied if promotion_exists_on_order?
86
+
83
87
  unless promotion.eligible?(order)
84
88
  self.error = promotion.eligibility_errors.full_messages.first unless promotion.eligibility_errors.blank?
85
89
  return (error || ineligible_for_this_order)
@@ -9,7 +9,7 @@ module Spree
9
9
  end
10
10
 
11
11
  def activate
12
- if promotion && promotion.eligible?(order)
12
+ if promotion&.eligible?(order)
13
13
  promotion.activate(order: order)
14
14
  end
15
15
  end
@@ -40,10 +40,10 @@ module Spree
40
40
 
41
41
  @new_promotion.promotion_actions << new_action
42
42
 
43
- if action.try(:promotion_action_line_items)
44
- action.promotion_action_line_items.each do |item|
45
- new_action.promotion_action_line_items << item.dup
46
- end
43
+ next unless action.try(:promotion_action_line_items)
44
+
45
+ action.promotion_action_line_items.each do |item|
46
+ new_action.promotion_action_line_items << item.dup
47
47
  end
48
48
  end
49
49
  end
@@ -58,7 +58,7 @@ module Spree
58
58
  payment.payment_method.credit(credit_cents, payment.source, payment.transaction_id, originator: self)
59
59
  else
60
60
  payment.payment_method.credit(credit_cents, payment.transaction_id, originator: self)
61
- end
61
+ end
62
62
 
63
63
  unless response.success?
64
64
  logger.error(Spree.t(:gateway_error) + " #{response.to_yaml}")
@@ -37,6 +37,7 @@ module Spree
37
37
  return valid_preferred_reimbursement_type?(return_item) ? return_item.preferred_reimbursement_type.class : nil
38
38
  end
39
39
  return expired_reimbursement_type if past_reimbursable_time_period?(return_item)
40
+
40
41
  default_reimbursement_type
41
42
  end
42
43
  end
@@ -24,13 +24,13 @@ module Spree
24
24
  0
25
25
  else
26
26
  return_item.pre_tax_amount / calculated_refund
27
- end
27
+ end
28
28
 
29
29
  additional_tax_total = percent_of_tax * return_item.inventory_unit.additional_tax_total
30
30
  included_tax_total = percent_of_tax * return_item.inventory_unit.included_tax_total
31
31
 
32
32
  return_item.update_attributes!(additional_tax_total: additional_tax_total,
33
- included_tax_total: included_tax_total)
33
+ included_tax_total: included_tax_total)
34
34
  end
35
35
  end
36
36
  end
@@ -151,6 +151,7 @@ module Spree
151
151
  # ever returned. This means that the inventory unit's line_item
152
152
  # will have a different variant than the inventory unit itself
153
153
  return unless exchange_required?
154
+
154
155
  exchange_inventory_units.build(variant: exchange_variant, line_item: inventory_unit.line_item,
155
156
  order: inventory_unit.order, quantity: return_quantity)
156
157
  end
@@ -163,6 +164,10 @@ module Spree
163
164
  self.pre_tax_amount = refund_amount_calculator.new.compute(self)
164
165
  end
165
166
 
167
+ def currency
168
+ return_authorization.try(:currency) || Spree::Config[:currency]
169
+ end
170
+
166
171
  private
167
172
 
168
173
  def persist_acceptance_status_errors
@@ -176,10 +181,6 @@ module Spree
176
181
  stock_location_id: customer_return.stock_location_id)
177
182
  end
178
183
 
179
- def currency
180
- return_authorization.try(:currency) || Spree::Config[:currency]
181
- end
182
-
183
184
  def process_inventory_unit!
184
185
  inventory_unit.return!
185
186
  if should_restock?
@@ -207,6 +208,7 @@ module Spree
207
208
 
208
209
  def eligible_exchange_variant
209
210
  return unless exchange_variant && exchange_variant_id_changed?
211
+
210
212
  unless eligible_exchange_variants.include?(exchange_variant)
211
213
  errors.add(:base, Spree.t(:invalid_exchange_variant))
212
214
  end
@@ -225,6 +227,7 @@ module Spree
225
227
  def sufficient_quantity_for_return
226
228
  # Only perform the check if everything is good so far
227
229
  return unless errors.empty? && return_quantity > inventory_unit.quantity
230
+
228
231
  errors.add(:return_quantity, Spree.t(:cannot_return_more_than_bought_quantity))
229
232
  end
230
233
 
@@ -2,12 +2,12 @@ module Spree
2
2
  class ReturnItem::EligibilityValidator::Default < Spree::ReturnItem::EligibilityValidator::BaseValidator
3
3
  class_attribute :permitted_eligibility_validators
4
4
  self.permitted_eligibility_validators = [
5
- ReturnItem::EligibilityValidator::OrderCompleted,
6
- ReturnItem::EligibilityValidator::TimeSincePurchase,
7
- ReturnItem::EligibilityValidator::RMARequired,
8
- ReturnItem::EligibilityValidator::InventoryShipped,
9
- ReturnItem::EligibilityValidator::NoReimbursements
10
- ]
5
+ ReturnItem::EligibilityValidator::OrderCompleted,
6
+ ReturnItem::EligibilityValidator::TimeSincePurchase,
7
+ ReturnItem::EligibilityValidator::RMARequired,
8
+ ReturnItem::EligibilityValidator::InventoryShipped,
9
+ ReturnItem::EligibilityValidator::NoReimbursements
10
+ ]
11
11
 
12
12
  def eligible_for_return?
13
13
  validators.all?(&:eligible_for_return?)
@@ -2,7 +2,7 @@ module Spree
2
2
  module ReturnItem::ExchangeVariantEligibility
3
3
  class SameProduct
4
4
  def self.eligible_variants(variant)
5
- Spree::Variant.where(product_id: variant.product_id, is_master: variant.is_master?).in_stock
5
+ Spree::Variant.where(product_id: variant.product_id, is_master: variant.is_master?).in_stock_or_backorderable
6
6
  end
7
7
  end
8
8
  end
@@ -75,8 +75,8 @@ module Spree
75
75
  after_transition do |shipment, transition|
76
76
  shipment.state_changes.create!(
77
77
  previous_state: transition.from,
78
- next_state: transition.to,
79
- name: 'shipment'
78
+ next_state: transition.to,
79
+ name: 'shipment'
80
80
  )
81
81
  end
82
82
  end
@@ -103,6 +103,7 @@ module Spree
103
103
  inventory_units.any?(&:backordered?)
104
104
  end
105
105
 
106
+ # TODO: delegate currency to Order, order.currency is mandatory
106
107
  def currency
107
108
  order ? order.currency : Spree::Config[:currency]
108
109
  end
@@ -117,6 +118,7 @@ module Spree
117
118
  return 'pending' unless order.can_ship?
118
119
  return 'pending' if inventory_units.any? &:backordered?
119
120
  return 'shipped' if shipped?
121
+
120
122
  order.paid? || Spree::Config[:auto_capture_on_dispatch] ? 'ready' : 'pending'
121
123
  end
122
124
 
@@ -133,6 +135,12 @@ module Spree
133
135
  item_cost + final_price
134
136
  end
135
137
 
138
+ def free?
139
+ return true if final_price == BigDecimal(0)
140
+
141
+ adjustments.promotion.any? { |p| p.source.type == 'Spree::Promotion::Actions::FreeShipping' }
142
+ end
143
+
136
144
  def finalize!
137
145
  inventory_units.finalize_units!
138
146
  after_resume
@@ -184,6 +192,7 @@ module Spree
184
192
 
185
193
  payments_pool = pending_payments.each_with_object([]) do |payment, pool|
186
194
  break if payments_amount >= shipment_to_pay
195
+
187
196
  payments_amount += payment.uncaptured_amount
188
197
  pool << payment
189
198
  end
@@ -243,6 +252,7 @@ module Spree
243
252
 
244
253
  def set_up_inventory(state, variant, order, line_item, quantity = 1)
245
254
  return if quantity <= 0
255
+
246
256
  inventory_units.create(
247
257
  state: state,
248
258
  variant_id: variant.id,
@@ -254,6 +264,7 @@ module Spree
254
264
 
255
265
  def shipped=(value)
256
266
  return unless value == '1' && shipped_at.nil?
267
+
257
268
  self.shipped_at = Time.current
258
269
  end
259
270
 
@@ -338,40 +349,22 @@ module Spree
338
349
  end
339
350
 
340
351
  def transfer_to_location(variant, quantity, stock_location)
341
- raise ArgumentError if quantity <= 0
342
-
343
- transaction do
344
- new_shipment = order.shipments.create!(stock_location: stock_location)
345
-
346
- order.contents.remove(variant, quantity, shipment: self)
347
- order.contents.add(variant, quantity, shipment: new_shipment)
348
- order.create_tax_charge!
349
- order.update_with_updater!
350
-
351
- refresh_rates
352
- save! if persisted?
353
- new_shipment.save!
354
- end
352
+ transfer_to_shipment(
353
+ variant,
354
+ quantity,
355
+ order.shipments.build(stock_location: stock_location)
356
+ )
355
357
  end
356
358
 
357
359
  def transfer_to_shipment(variant, quantity, shipment_to_transfer_to)
358
- quantity_already_shipment_to_transfer_to = shipment_to_transfer_to.manifest.find do |mi|
359
- mi.line_item.variant == variant
360
- end.try(:quantity) || 0
361
- final_quantity = quantity + quantity_already_shipment_to_transfer_to
362
-
363
- raise ArgumentError if quantity <= 0 || self == shipment_to_transfer_to
364
-
365
- transaction do
366
- order.contents.remove(variant, final_quantity, shipment: self)
367
- order.contents.add(variant, final_quantity, shipment: shipment_to_transfer_to)
368
- order.update_with_updater!
369
-
370
- refresh_rates
371
- save! if persisted?
372
- shipment_to_transfer_to.refresh_rates
373
- shipment_to_transfer_to.save!
374
- end
360
+ Spree::FulfilmentChanger.new(
361
+ current_stock_location: stock_location,
362
+ desired_stock_location: shipment_to_transfer_to.stock_location,
363
+ current_shipment: self,
364
+ desired_shipment: shipment_to_transfer_to,
365
+ variant: variant,
366
+ quantity: quantity
367
+ ).run!
375
368
  end
376
369
 
377
370
  private
@@ -381,7 +374,7 @@ module Spree
381
374
  end
382
375
 
383
376
  def can_get_rates?
384
- order.ship_address && order.ship_address.valid?
377
+ order.ship_address&.valid?
385
378
  end
386
379
 
387
380
  def manifest_restock(item)
@@ -27,6 +27,7 @@ module Spree
27
27
 
28
28
  def include?(address)
29
29
  return false unless address
30
+
30
31
  zones.includes(:zone_members).any? do |zone|
31
32
  zone.include?(address)
32
33
  end
@@ -34,6 +35,7 @@ module Spree
34
35
 
35
36
  def build_tracking_url(tracking)
36
37
  return if tracking.blank? || tracking_url.blank?
38
+
37
39
  tracking_url.gsub(/:tracking/, ERB::Util.url_encode(tracking)) # :url_encode exists in 1.8.7 through 2.1.0
38
40
  end
39
41
 
@@ -1,36 +1,35 @@
1
1
  module Spree
2
2
  class ShippingRate < Spree::Base
3
3
  belongs_to :shipment, class_name: 'Spree::Shipment'
4
- belongs_to :shipping_method, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates
5
4
  belongs_to :tax_rate, class_name: 'Spree::TaxRate'
6
-
7
- delegate :order, :currency, to: :shipment
8
- delegate :name, to: :shipping_method
9
- delegate :code, to: :shipping_method, prefix: true
5
+ belongs_to :shipping_method, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates
10
6
 
11
7
  extend Spree::DisplayMoney
12
8
 
13
- money_methods :base_price, :tax_amount
9
+ money_methods :base_price, :final_price, :tax_amount
14
10
 
15
- def base_price
16
- cost
17
- end
11
+ delegate :order, :currency, :free?, to: :shipment
12
+ delegate :name, to: :shipping_method
13
+ delegate :code, to: :shipping_method, prefix: true
18
14
 
19
15
  def display_price
20
16
  price = display_base_price.to_s
21
17
 
22
- return price if tax_rate.nil? || tax_amount == 0
18
+ return price if tax_rate.nil? || tax_amount.zero?
23
19
 
24
- Spree.t tax_rate.included_in_price? ? :including_tax : :excluding_tax,
25
- scope: 'shipping_rates.display_price',
26
- price: price,
27
- tax_amount: display_tax_amount,
28
- tax_rate_name: tax_rate.name
20
+ Spree.t(
21
+ tax_rate.included_in_price? ? :including_tax : :excluding_tax,
22
+ scope: 'shipping_rates.display_price',
23
+ price: price,
24
+ tax_amount: display_tax_amount,
25
+ tax_rate_name: tax_rate.name
26
+ )
29
27
  end
30
28
  alias display_cost display_price
29
+ alias_attribute :base_price, :cost
31
30
 
32
31
  def tax_amount
33
- @_tax_amount ||= tax_rate.calculator.compute_shipping_rate(self)
32
+ @tax_amount ||= tax_rate&.calculator&.compute_shipping_rate(self) || BigDecimal(0)
34
33
  end
35
34
 
36
35
  def shipping_method
@@ -40,5 +39,21 @@ module Spree
40
39
  def tax_rate
41
40
  Spree::TaxRate.unscoped { super }
42
41
  end
42
+
43
+ # returns base price - any available discounts for this Shipment
44
+ # useful when you want to present a list of available shipping rates
45
+ def final_price
46
+ if free? || cost < -discount_amount
47
+ BigDecimal(0)
48
+ else
49
+ cost + discount_amount
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def discount_amount
56
+ shipment.adjustments.promotion.sum(:amount)
57
+ end
43
58
  end
44
59
  end