diff --git a/app/forms/standing_order_form.rb b/app/forms/standing_order_form.rb index 6dbe92960e..213bcd6ac0 100644 --- a/app/forms/standing_order_form.rb +++ b/app/forms/standing_order_form.rb @@ -18,6 +18,7 @@ class StandingOrderForm validate :schedule_allowed? validate :payment_method_allowed? validate :shipping_method_allowed? + validate :standing_line_items_present? validate :standing_line_items_available? def initialize(standing_order, params={}, fee_calculator=nil) @@ -209,6 +210,12 @@ class StandingOrderForm end end + def standing_line_items_present? + unless standing_line_items.reject(&:marked_for_destruction?).any? + errors.add(:standing_line_items, :at_least_one_product) + end + end + def standing_line_items_available? standing_line_items.each do |sli| unless sli.available_from?(shop_id, schedule_id) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5c77fe6c2b..7b7e27ab92 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -76,6 +76,7 @@ en: standing_order_form: attributes: standing_line_items: + at_least_one_product: "^Please add at least one product" not_available: "^%{name} is not available from the selected schedule" devise: confirmations: diff --git a/spec/forms/standing_order_form_spec.rb b/spec/forms/standing_order_form_spec.rb index 42b84a99a5..05eb3d01e6 100644 --- a/spec/forms/standing_order_form_spec.rb +++ b/spec/forms/standing_order_form_spec.rb @@ -384,12 +384,32 @@ describe StandingOrderForm do let(:params) { { standing_line_items_attributes: [ { id: sli.id, _destroy: true } ] } } let(:form) { StandingOrderForm.new(standing_order, params) } - it "removes the line item and updates totals on all orders" do - expect(order.reload.total.to_f).to eq 59.97 - expect(form.save).to be true - line_items = Spree::LineItem.where(order_id: standing_order.orders, variant_id: variant.id) - expect(line_items.count).to be 0 - expect(order.reload.total.to_f).to eq 39.98 + context "that is not the last remaining item" do + it "removes the line item and updates totals on all orders" do + expect(order.reload.total.to_f).to eq 59.97 + expect(form.save).to be true + line_items = Spree::LineItem.where(order_id: standing_order.orders, variant_id: variant.id) + expect(line_items.count).to be 0 + expect(order.reload.total.to_f).to eq 39.98 + end + end + + context "that is the last remaining item" do + before do + standing_order.standing_line_items.where('variant_id != ?',variant.id).destroy_all + order.line_items.where('variant_id != ?',variant.id).destroy_all + standing_order.reload + order.reload + end + + it "returns false and does not remove the line item or update totals on orders" do + expect(order.reload.total.to_f).to eq 19.99 + expect(form.save).to be false + line_items = Spree::LineItem.where(order_id: standing_order.orders, variant_id: variant.id) + expect(line_items.count).to be 1 + expect(order.reload.total.to_f).to eq 19.99 + expect(form.json_errors.keys).to eq [:standing_line_items] + end end end