solidus_core 2.0.0.beta1 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db4e0e9709867fb934de7f6250cf594afbc087c6
4
- data.tar.gz: 13f9c0f6043e15d1411234d0a341b80242ba58fb
3
+ metadata.gz: fbdfb658bce9038100b17820c195754a991baaa5
4
+ data.tar.gz: 08313688df1befda337af2e52baab5149c510940
5
5
  SHA512:
6
- metadata.gz: d1b74e57ddb5daa0c9066ee20766af6bfc5d825fefb21f52c007eb79484599c6590e0acfb445de074b91c7e3de419ad26b4593937842f7601237cad14379426d
7
- data.tar.gz: 6fe815393c2fbee2d930fc52157e1679c2e8b4b228f3d99ea13a5b54d67161cb4e8aa7affbc1ee0a55e39bdae8be67fe0949c4df9514210d6c8c1eeb45069af7
6
+ metadata.gz: f76f20c1fc3ca55a230b8cee008b4a6ffd1c228b07dcb9cc2ab317bd53d995a8a6cb262c39ef54db1bc2e587b68b3ba9b223cbf81a7eb951ecc7a5a89b5b7a7c
7
+ data.tar.gz: 6233bcf5c299863d50f6e9f983b6b928af5cd596368a0c86ad956b62f0acc8583a54e61a806891954c91d736499d5799d79721b956ed6e051b78e340a39cefca
@@ -26,6 +26,11 @@ module Spree
26
26
  validates :amount, numericality: true
27
27
  validates :promotion_code, presence: true, if: :require_promotion_code?
28
28
 
29
+ # We need to use `after_commit` here because otherwise it's too early to
30
+ # tell if any repair is needed.
31
+ after_commit :repair_adjustments_associations_on_create, on: [:create]
32
+ after_commit :repair_adjustments_associations_on_destroy, on: [:destroy]
33
+
29
34
  scope :not_finalized, -> { where(finalized: false) }
30
35
  scope :open, -> do
31
36
  Spree::Deprecation.warn "Adjustment.open is deprecated. Instead use Adjustment.not_finalized", caller
@@ -177,5 +182,19 @@ module Spree
177
182
  def require_promotion_code?
178
183
  promotion? && source.promotion.codes.any?
179
184
  end
185
+
186
+ def repair_adjustments_associations_on_create
187
+ if adjustable.adjustments.loaded? && !adjustable.adjustments.include?(self)
188
+ Spree::Deprecation.warn("Adjustment was not added to #{adjustable.class}. Add adjustments via `adjustable.adjustments.create!`. Partial call stack: #{caller.select { |line| line =~ %r(/(app|spec)/) }}.", caller)
189
+ adjustable.adjustments.proxy_association.add_to_target(self)
190
+ end
191
+ end
192
+
193
+ def repair_adjustments_associations_on_destroy
194
+ if adjustable.adjustments.loaded? && adjustable.adjustments.include?(self)
195
+ Spree::Deprecation.warn("Adjustment was not removed from #{adjustable.class}. Remove adjustments via `adjustable.adjustments.destroy`. Partial call stack: #{caller.select { |line| line =~ %r(/(app|spec)/) }}.", caller)
196
+ adjustable.adjustments.proxy_association.target.delete(self)
197
+ end
198
+ end
180
199
  end
181
200
  end
@@ -83,11 +83,7 @@ module Spree
83
83
  private
84
84
 
85
85
  def adjustments
86
- # This is done intentionally to avoid loading the association. If the
87
- # association is loaded, the records may become stale due to code
88
- # elsewhere in spree. When that is remedied, this should be changed to
89
- # just item.adjustments
90
- @adjustments ||= item.adjustments.all.to_a
86
+ @adjustments ||= item.adjustments.to_a
91
87
  end
92
88
  end
93
89
  end
@@ -43,10 +43,6 @@ module Spree
43
43
  break if payment_total >= total
44
44
 
45
45
  payment.public_send(method)
46
-
47
- if payment.completed?
48
- self.payment_total += payment.amount
49
- end
50
46
  end
51
47
  rescue Core::GatewayError => e
52
48
  result = !!Spree::Config[:allow_checkout_on_gateway_error]
@@ -47,7 +47,7 @@ module Spree
47
47
  belongs_to :store, class_name: 'Spree::Store'
48
48
  has_many :state_changes, as: :stateful
49
49
  has_many :line_items, -> { order(:created_at, :id) }, dependent: :destroy, inverse_of: :order
50
- has_many :payments, dependent: :destroy
50
+ has_many :payments, dependent: :destroy, inverse_of: :order
51
51
  has_many :return_authorizations, dependent: :destroy, inverse_of: :order
52
52
  has_many :reimbursements, inverse_of: :order
53
53
  has_many :adjustments, -> { order(:created_at) }, as: :adjustable, inverse_of: :adjustable, dependent: :destroy
@@ -503,7 +503,6 @@ module Spree
503
503
  elsif shipments.any? { |s| !s.pending? }
504
504
  raise CannotRebuildShipments.new(Spree.t(:cannot_rebuild_shipments_shipments_not_pending))
505
505
  else
506
- adjustments.shipping.destroy_all
507
506
  shipments.destroy_all
508
507
  self.shipments = Spree::Config.stock.coordinator_class.new(self).shipments
509
508
  end
@@ -511,9 +510,7 @@ module Spree
511
510
 
512
511
  def apply_free_shipping_promotions
513
512
  Spree::PromotionHandler::FreeShipping.new(self).activate
514
- shipments.each { |shipment| ItemAdjustments.new(shipment).update }
515
- updater.update_shipment_total
516
- persist_totals
513
+ update!
517
514
  end
518
515
 
519
516
  # Clean shipments and make order back to address state
@@ -21,22 +21,15 @@ class Spree::OrderCapturing
21
21
  Spree::OrderMutex.with_lock!(@order) do
22
22
  uncaptured_amount = @order.display_total.cents
23
23
 
24
- begin
25
- sorted_payments(@order).each do |payment|
26
- amount = [uncaptured_amount, payment.money.cents].min
27
-
28
- if amount > 0
29
- payment.capture!(amount)
30
- uncaptured_amount -= amount
31
- elsif Spree::OrderCapturing.void_unused_payments
32
- payment.void_transaction!
33
- end
24
+ sorted_payments(@order).each do |payment|
25
+ amount = [uncaptured_amount, payment.money.cents].min
26
+
27
+ if amount > 0
28
+ payment.capture!(amount)
29
+ uncaptured_amount -= amount
30
+ elsif Spree::OrderCapturing.void_unused_payments
31
+ payment.void_transaction!
34
32
  end
35
- ensure
36
- # FIXME: Adding the inverse_of on the payments relation for orders -should- fix this,
37
- # however it only appears to make it worse (calling with changes three times instead of once.
38
- # Warrants an investigation. Reloading for now.
39
- @order.reload.update!
40
33
  end
41
34
  end
42
35
  end
@@ -119,7 +119,6 @@ module Spree
119
119
  shipment = options[:shipment]
120
120
  shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
121
121
  PromotionHandler::Cart.new(order, line_item).activate
122
- ItemAdjustments.new(line_item).update
123
122
  reload_totals
124
123
  line_item
125
124
  end
@@ -80,11 +80,11 @@ module Spree
80
80
 
81
81
  all_items = line_items + shipments
82
82
 
83
- order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.eligible.sum(:amount)
83
+ order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.select(&:eligible?).sum(&:amount)
84
84
  order.included_tax_total = all_items.sum(&:included_tax_total)
85
85
  order.additional_tax_total = all_items.sum(&:additional_tax_total)
86
86
 
87
- order.promo_total = all_items.sum(&:promo_total) + adjustments.promotion.eligible.sum(:amount)
87
+ order.promo_total = all_items.sum(&:promo_total) + adjustments.select(&:eligible?).select(&:promotion?).sum(&:amount)
88
88
 
89
89
  update_order_total
90
90
  end
@@ -22,10 +22,9 @@ module Spree
22
22
  return if promotion_credit_exists?(order)
23
23
 
24
24
  amount = compute_amount(order)
25
- Spree::Adjustment.create!(
25
+ order.adjustments.create!(
26
26
  amount: amount,
27
27
  order: order,
28
- adjustable: order,
29
28
  source: self,
30
29
  promotion_code: options[:promotion_code],
31
30
  label: "#{Spree.t(:promotion)} (#{promotion.name})"
@@ -40,9 +40,9 @@ module Spree
40
40
  def create_adjustment(adjustable, order, promotion_code)
41
41
  amount = compute_amount(adjustable)
42
42
  return if amount == 0
43
- adjustments.create!(
43
+ adjustable.adjustments.create!(
44
+ source: self,
44
45
  amount: amount,
45
- adjustable: adjustable,
46
46
  order: order,
47
47
  promotion_code: promotion_code,
48
48
  label: "#{Spree.t(:promotion)} (#{promotion.name})"
@@ -15,7 +15,6 @@ module Spree
15
15
  @rates_for_order_zone = options[:rates_for_order_zone]
16
16
  @rates_for_default_zone = options[:rates_for_default_zone]
17
17
  @order_tax_zone = options[:order_tax_zone]
18
- @skip_destroy_adjustments = options[:skip_destroy_adjustments]
19
18
  end
20
19
 
21
20
  # Deletes all existing tax adjustments and creates new adjustments for all
@@ -27,8 +26,8 @@ module Spree
27
26
  # @return [Array<Spree::Adjustment>] newly created adjustments
28
27
  def adjust!
29
28
  return unless order_tax_zone(order)
30
- # Using .destroy_all to make sure callbacks fire
31
- item.adjustments.tax.destroy_all unless @skip_destroy_adjustments
29
+
30
+ item.adjustments.destroy(item.adjustments.select(&:tax?))
32
31
 
33
32
  rates_for_item(item).map { |rate| rate.adjust(order_tax_zone(order), item) }
34
33
  end
@@ -16,8 +16,6 @@ module Spree
16
16
  def adjust!
17
17
  return unless order_tax_zone(order)
18
18
 
19
- order.all_adjustments.tax.destroy_all
20
-
21
19
  (order.line_items + order.shipments).each do |item|
22
20
  ItemAdjuster.new(item, order_wide_options).adjust!
23
21
  end
@@ -30,7 +28,6 @@ module Spree
30
28
  rates_for_order_zone: rates_for_order_zone(order),
31
29
  rates_for_default_zone: rates_for_default_zone,
32
30
  order_tax_zone: order_tax_zone(order),
33
- skip_destroy_adjustments: true
34
31
  }
35
32
  end
36
33
  end
@@ -85,13 +85,13 @@ module Spree
85
85
 
86
86
  included = included_in_price && amount > 0
87
87
 
88
- adjustments.create!({
89
- adjustable: item,
88
+ item.adjustments.create!(
89
+ source: self,
90
90
  amount: amount,
91
91
  order_id: item.order_id,
92
92
  label: adjustment_label(amount),
93
93
  included: included
94
- })
94
+ )
95
95
  end
96
96
 
97
97
  # This method is used by Adjustment#update to recalculate the cost.
@@ -16,8 +16,8 @@ class Spree::UnitCancel < Spree::Base
16
16
 
17
17
  amount = compute_amount(inventory_unit.line_item)
18
18
 
19
- create_adjustment!(
20
- adjustable: inventory_unit.line_item,
19
+ self.adjustment = inventory_unit.line_item.adjustments.create!(
20
+ source: self,
21
21
  amount: amount,
22
22
  order: inventory_unit.order,
23
23
  label: "#{Spree.t(:cancellation)} - #{reason}",
@@ -5,7 +5,7 @@ module Spree
5
5
  end
6
6
 
7
7
  def self.solidus_version
8
- "2.0.0.beta1"
8
+ "2.0.0.rc1"
9
9
  end
10
10
 
11
11
  def self.solidus_gem_version
@@ -12,22 +12,27 @@ FactoryGirl.define do
12
12
  label 'Shipping'
13
13
  association(:source, factory: :tax_rate)
14
14
  eligible true
15
- end
16
15
 
17
- factory :tax_adjustment, class: Spree::Adjustment do
18
- order { adjustable.order }
19
- association(:adjustable, factory: :line_item)
20
- amount 10.0
21
- label 'VAT 5%'
22
- association(:source, factory: :tax_rate)
23
- eligible true
16
+ after(:build) do |adjustment|
17
+ adjustments = adjustment.adjustable.adjustments
18
+ if adjustments.loaded? && !adjustments.include?(adjustment)
19
+ adjustments.proxy_association.add_to_target(adjustment)
20
+ end
21
+ end
22
+
23
+ factory :tax_adjustment, class: Spree::Adjustment do
24
+ order { adjustable.order }
25
+ association(:adjustable, factory: :line_item)
26
+ amount 10.0
27
+ label 'VAT 5%'
24
28
 
25
- after(:create) do |adjustment|
26
- # Set correct tax category, so that adjustment amount is not 0
27
- if adjustment.adjustable.is_a?(Spree::LineItem)
28
- adjustment.source.tax_category = adjustment.adjustable.tax_category
29
- adjustment.source.save
30
- adjustment.update!
29
+ after(:create) do |adjustment|
30
+ # Set correct tax category, so that adjustment amount is not 0
31
+ if adjustment.adjustable.is_a?(Spree::LineItem)
32
+ adjustment.source.tax_category = adjustment.adjustable.tax_category
33
+ adjustment.source.save
34
+ adjustment.update!
35
+ end
31
36
  end
32
37
  end
33
38
  end
@@ -18,7 +18,7 @@ describe "order_capturing:capture_payments" do
18
18
 
19
19
  context "with a mix of canceled and shipped inventory" do
20
20
  before do
21
- Spree::OrderCancellations.new(order).short_ship([order.inventory_units.first])
21
+ Spree::OrderCancellations.new(order).short_ship([order.line_items.first.inventory_units.first])
22
22
  order.shipping.ship_shipment(order.shipments.first)
23
23
  order.update_attributes!(payment_state: 'balance_due')
24
24
  end
@@ -272,6 +272,9 @@ module Spree
272
272
  context "multiple updates" do
273
273
  let(:adjustment) { create(:tax_adjustment, amount: -10) }
274
274
  let(:item) { adjustment.adjustable }
275
+ # we need to get this from the line item so that we're modifying the same
276
+ # tax rate that is cached by line_item.adjustments
277
+ let(:source) { item.adjustments.to_a.first.source }
275
278
 
276
279
  def update
277
280
  described_class.new(item).update
@@ -283,18 +286,17 @@ module Spree
283
286
  end
284
287
 
285
288
  it "persists each change" do
286
- adjustment.source.update_attributes!(amount: 0.1)
289
+ source.update_attributes!(amount: 0.1)
287
290
  update
288
291
  expect(item).not_to be_changed
289
292
  expect(db_record).to have_attributes(adjustment_total: 1)
290
293
 
291
- adjustment.source.update_attributes!(amount: 0.20)
292
- item.reload
294
+ source.update_attributes!(amount: 0.20)
293
295
  update
294
296
  expect(item).not_to be_changed
295
297
  expect(db_record).to have_attributes(adjustment_total: 2)
296
298
 
297
- adjustment.source.update_attributes!(amount: 0.10)
299
+ source.update_attributes!(amount: 0.10)
298
300
  update
299
301
  expect(item).not_to be_changed
300
302
  expect(db_record).to have_attributes(adjustment_total: 1)
@@ -6,49 +6,53 @@ module Spree
6
6
  let(:updater) { Spree::OrderUpdater.new(order) }
7
7
 
8
8
  context "processing payments" do
9
+ let(:order) { create(:order_with_line_items, shipment_cost: 0, line_items_price: 100) }
9
10
  before do
10
11
  # So that Payment#purchase! is called during processing
11
12
  Spree::Config[:auto_capture] = true
12
-
13
- allow(order).to receive_message_chain(:line_items, :empty?).and_return(false)
14
- allow(order).to receive_messages total: 100
15
13
  end
16
14
 
17
15
  it 'processes all checkout payments' do
18
- payment_1 = create(:payment, amount: 50)
19
- payment_2 = create(:payment, amount: 50)
20
- allow(order).to receive(:unprocessed_payments).and_return([payment_1, payment_2])
16
+ payment_1 = create(:payment, order: order, amount: 50)
17
+ payment_2 = create(:payment, order: order, amount: 50)
21
18
 
22
19
  order.process_payments!
23
20
  updater.update_payment_state
21
+
24
22
  expect(order.payment_state).to eq('paid')
23
+ expect(order.payment_total).to eq(100)
25
24
 
26
- expect(payment_1).to be_completed
27
- expect(payment_2).to be_completed
25
+ expect(payment_1.reload).to be_completed
26
+ expect(payment_2.reload).to be_completed
28
27
  end
29
28
 
30
29
  it 'does not go over total for order' do
31
- payment_1 = create(:payment, amount: 50)
32
- payment_2 = create(:payment, amount: 50)
33
- payment_3 = create(:payment, amount: 50)
34
- allow(order).to receive(:unprocessed_payments).and_return([payment_1, payment_2, payment_3])
30
+ payment_1 = create(:payment, order: order, amount: 50)
31
+ payment_2 = create(:payment, order: order, amount: 50)
32
+ payment_3 = create(:payment, order: order, amount: 50)
35
33
 
36
34
  order.process_payments!
37
35
  updater.update_payment_state
36
+
38
37
  expect(order.payment_state).to eq('paid')
38
+ expect(order.payment_total).to eq(100)
39
39
 
40
- expect(payment_1).to be_completed
41
- expect(payment_2).to be_completed
42
- expect(payment_3).to be_checkout
40
+ expect(payment_1.reload).to be_completed
41
+ expect(payment_2.reload).to be_completed
42
+ expect(payment_3.reload).to be_checkout
43
43
  end
44
44
 
45
45
  it "does not use failed payments" do
46
- payment_1 = create(:payment, amount: 50)
47
- payment_2 = create(:payment, amount: 50, state: 'failed')
46
+ create(:payment, order: order, amount: 50)
47
+ create(:payment, order: order, amount: 50, state: 'failed')
48
+ order.payments.reload
48
49
 
49
- expect(payment_2).not_to receive(:process!)
50
+ expect(order.payments[0]).to receive(:process!).and_call_original
51
+ expect(order.payments[1]).not_to receive(:process!)
50
52
 
51
53
  order.process_payments!
54
+
55
+ expect(order.payment_total).to eq(50)
52
56
  end
53
57
  end
54
58
 
@@ -139,9 +139,9 @@ describe Spree::OrderCancellations do
139
139
  order.contents.add(line_item.variant)
140
140
 
141
141
  # make the total $1.67 so it divides unevenly
142
- Spree::Adjustment.tax.create!(
142
+ line_item.adjustments.create!(
143
+ source_type: 'Spree::TaxRate',
143
144
  order: order,
144
- adjustable: line_item,
145
145
  amount: 0.01,
146
146
  label: 'some fake tax',
147
147
  finalized: true
@@ -4,8 +4,8 @@ describe Spree::OrderCapturing do
4
4
  describe '#capture_payments' do
5
5
  subject { Spree::OrderCapturing.new(order, payment_methods).capture_payments }
6
6
 
7
- # Regression for the order.update! in the ensure block.
8
- # See the comment there.
7
+ # Regression for https://github.com/solidusio/solidus/pull/407
8
+ # See also https://github.com/solidusio/solidus/pull/1406
9
9
  context "updating the order" do
10
10
  let(:order) { create :completed_order_with_totals }
11
11
  let(:payment_methods) { [] }
@@ -591,16 +591,12 @@ describe Spree::Order, type: :model do
591
591
 
592
592
  context "#apply_free_shipping_promotions" do
593
593
  it "calls out to the FreeShipping promotion handler" do
594
- shipment = double('Shipment')
595
- allow(order).to receive_messages shipments: [shipment]
596
- expect(Spree::PromotionHandler::FreeShipping).to receive(:new).and_return(handler = double)
597
- expect(handler).to receive(:activate)
594
+ expect_any_instance_of(Spree::PromotionHandler::FreeShipping).to(
595
+ receive(:activate)
596
+ ).and_call_original
598
597
 
599
- expect(Spree::ItemAdjustments).to receive(:new).with(shipment).and_return(adjuster = double)
600
- expect(adjuster).to receive(:update)
598
+ expect(order.updater).to receive(:update).and_call_original
601
599
 
602
- expect(order.updater).to receive(:update_shipment_total)
603
- expect(order.updater).to receive(:persist_totals)
604
600
  order.apply_free_shipping_promotions
605
601
  end
606
602
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe Spree::Tax::ItemAdjuster do
4
4
  subject(:adjuster) { described_class.new(item) }
5
- let(:order) { Spree::Order.new }
5
+ let(:order) { create(:order) }
6
6
  let(:item) { Spree::LineItem.new(order: order) }
7
7
 
8
8
  before do
@@ -64,7 +64,6 @@ RSpec.describe Spree::Tax::ItemAdjuster do
64
64
  before { allow(item).to receive(:tax_category).and_return(item_tax_category) }
65
65
 
66
66
  it 'creates an adjustment for every matching rate' do
67
- expect(rate_1).to receive_message_chain(:adjustments, :create!)
68
67
  expect(adjuster.adjust!.length).to eq(1)
69
68
  end
70
69
  end
@@ -31,7 +31,6 @@ RSpec.describe Spree::Tax::OrderAdjuster do
31
31
  rates_for_order_zone: rates_for_order_zone,
32
32
  rates_for_default_zone: [],
33
33
  order_tax_zone: zone,
34
- skip_destroy_adjustments: true
35
34
  ).and_return(item_adjuster)
36
35
  expect(Spree::Tax::ItemAdjuster).to receive(:new).
37
36
  with(
@@ -39,7 +38,6 @@ RSpec.describe Spree::Tax::OrderAdjuster do
39
38
  rates_for_order_zone: rates_for_order_zone,
40
39
  rates_for_default_zone: [],
41
40
  order_tax_zone: zone,
42
- skip_destroy_adjustments: true
43
41
  ).and_return(item_adjuster)
44
42
 
45
43
  expect(item_adjuster).to receive(:adjust!).twice
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta1
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-19 00:00:00.000000000 Z
11
+ date: 2016-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemerchant