From 912aa90ac4f422f0bde8bd7ad311d3a59b29b0cd Mon Sep 17 00:00:00 2001 From: Jeff Dutil Date: Thu, 14 Aug 2014 18:02:06 -0400 Subject: [PATCH 01/16] Fix importing source with payment profiles. --- core/app/models/spree/credit_card.rb | 9 ++++++--- core/app/models/spree/payment.rb | 2 ++ core/lib/spree/core/importer/order.rb | 9 ++++----- core/spec/models/spree/credit_card_spec.rb | 9 +++++++++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/core/app/models/spree/credit_card.rb b/core/app/models/spree/credit_card.rb index 8135db88900..3f6403f64b5 100644 --- a/core/app/models/spree/credit_card.rb +++ b/core/app/models/spree/credit_card.rb @@ -5,12 +5,15 @@ class CreditCard < Spree::Base before_create :set_missing_info - attr_accessor :number, :verification_value, :encrypted_data + attr_accessor :encrypted_data, + :number, + :imported, + :verification_value validates :month, :year, numericality: { only_integer: true }, if: :require_card_numbers?, on: :create - validates :number, presence: true, if: :require_card_numbers?, on: :create + validates :number, presence: true, if: :require_card_numbers?, on: :create, unless: :imported validates :name, presence: true, if: :require_card_numbers?, on: :create - validates :verification_value, presence: true, if: :require_card_numbers?, on: :create + validates :verification_value, presence: true, if: :require_card_numbers?, on: :create, unless: :imported validate :expiry_not_in_the_past diff --git a/core/app/models/spree/payment.rb b/core/app/models/spree/payment.rb index e34639a8435..29bfa32a575 100644 --- a/core/app/models/spree/payment.rb +++ b/core/app/models/spree/payment.rb @@ -173,6 +173,8 @@ def profiles_supported? def create_payment_profile return unless source.respond_to?(:has_payment_profile?) && !source.has_payment_profile? + # Imported payments shouldn't create a payment profile. + return if source.imported payment_method.create_profile(self) rescue ActiveMerchant::ConnectionError => e diff --git a/core/lib/spree/core/importer/order.rb b/core/lib/spree/core/importer/order.rb index c42ee699473..3c04e838575 100644 --- a/core/lib/spree/core/importer/order.rb +++ b/core/lib/spree/core/importer/order.rb @@ -143,13 +143,12 @@ def self.create_source_payment_from_params(source_hash, payment) last_digits: source_hash[:last_digits], name: source_hash[:name], payment_method: payment.payment_method, - # Number & Verification value are required attributes - # so just assigning fakes that are dropped when last_digits present. - number: '4111111111111111', - verification_value: '123' + gateway_customer_profile_id: source_hash[:gateway_customer_profile_id], + gateway_payment_profile_id: source_hash[:gateway_customer_profile_id], + imported: true ) rescue Exception => e - raise "Order import source payments: #{e.message} #{s}" + raise "Order import source payments: #{e.message} #{source_hash}" end end diff --git a/core/spec/models/spree/credit_card_spec.rb b/core/spec/models/spree/credit_card_spec.rb index f3194fc71d6..6972f846858 100644 --- a/core/spec/models/spree/credit_card_spec.rb +++ b/core/spec/models/spree/credit_card_spec.rb @@ -157,6 +157,15 @@ def stub_rails_env(environment) expect(credit_card.errors[:verification_value]).to be_empty end end + + context "imported is true" do + it "does not validate presence of number or cvv" do + credit_card.imported = true + credit_card.valid? + expect(credit_card.errors[:number]).to be_empty + expect(credit_card.errors[:verification_value]).to be_empty + end + end end context "#create" do From 38cb99d879fed66789aac0a239f654a3ae40063c Mon Sep 17 00:00:00 2001 From: Jeff Dutil Date: Thu, 14 Aug 2014 18:13:15 -0400 Subject: [PATCH 02/16] Fix cc stub. --- core/spec/models/spree/payment_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/spec/models/spree/payment_spec.rb b/core/spec/models/spree/payment_spec.rb index 61f74844a05..b4d39e07453 100644 --- a/core/spec/models/spree/payment_spec.rb +++ b/core/spec/models/spree/payment_spec.rb @@ -10,8 +10,9 @@ end let(:card) do - mock_model(Spree::CreditCard, :number => "4111111111111111", - :has_payment_profile? => true) + mock_model(Spree::CreditCard, number: "4111111111111111", + has_payment_profile?: true, + imported: false) end let(:payment) do From 08ec0effc6bd4205e4703f1adc4e6e8de96355e5 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Fri, 15 Aug 2014 10:47:29 +0200 Subject: [PATCH 03/16] extract helper methods into spree --- core/app/models/spree/line_item.rb | 14 ++++++++++ core/app/models/spree/stock_movement.rb | 9 +++++++ .../controllers/spree/checkout_controller.rb | 27 ++++++++++++++++--- .../controllers/spree/content_controller.rb | 2 +- .../controllers/spree/orders_controller.rb | 5 ++++ 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/core/app/models/spree/line_item.rb b/core/app/models/spree/line_item.rb index 25517ef59f3..4d8bc6bcf74 100644 --- a/core/app/models/spree/line_item.rb +++ b/core/app/models/spree/line_item.rb @@ -33,6 +33,7 @@ class LineItem < Spree::Base delegate :name, :description, :sku, :should_track_inventory?, to: :variant attr_accessor :target_shipment + attr_accessor :deleted def copy_price if variant @@ -95,6 +96,19 @@ def variant Spree::Variant.unscoped { super } end + + def single_vat + I18n.t("products.vat", vat: self.tax_category.tax_rates.first.amount * 100) + end + + def single_vat_name + I18n.t("products.vat", vat: self.tax_category.tax_rates.first.name.split(" ").last) + end + + def display_tax_description + I18n.t "cart.lineitem.#{self.tax_category.description.downcase.gsub(" ", "-")}" + end + private def update_inventory if (changed? || target_shipment.present?) && self.order.has_checkout_step?("delivery") diff --git a/core/app/models/spree/stock_movement.rb b/core/app/models/spree/stock_movement.rb index 90c6472b5a6..9e3a7fa39d2 100644 --- a/core/app/models/spree/stock_movement.rb +++ b/core/app/models/spree/stock_movement.rb @@ -18,9 +18,18 @@ def readonly? def update_stock_item_quantity return unless self.stock_item.should_track_inventory? + + # FR: Update all backordered orders + begin + self.stock_item.variant.inventory_units.each {|iu| iu.order.update! } + rescue + # just skip this for now + end + stock_item.adjust_count_on_hand quantity end end end + diff --git a/frontend/app/controllers/spree/checkout_controller.rb b/frontend/app/controllers/spree/checkout_controller.rb index d481a22b0cd..3bc5ff3677b 100644 --- a/frontend/app/controllers/spree/checkout_controller.rb +++ b/frontend/app/controllers/spree/checkout_controller.rb @@ -6,6 +6,9 @@ module Spree class CheckoutController < Spree::StoreController ssl_required + before_action -> { store_location } + before_action -> { save_user_addresses } + before_filter :load_order_with_lock before_filter :ensure_order_not_completed @@ -46,6 +49,24 @@ def update end private + + + + def save_marketing + if params["order"] && params["order"]["accepts_marketing"] + sub = Formrausch::Subscription.create_from_order(current_order) + if sub.valid? + sub.send_to_campaign_monitor(false, ENV["CAMPAIGN_MONITOR_CHECKOUT_LIST_ID"]) + end + @order.accepts_marketing = true + @order.save + end + end + + private def save_user_addresses + current_order.save_user_address(spree_current_user) + end + def ensure_valid_state unless skip_state_validation? if (params[:state] && !@order.has_checkout_step?(params[:state])) || @@ -107,10 +128,8 @@ def setup_for_current_state end def before_address - # if the user has a default address, a callback takes care of setting - # that; but if he doesn't, we need to build an empty one here - @order.bill_address ||= Address.build_default - @order.ship_address ||= Address.build_default if @order.checkout_steps.include?('delivery') + @order.bill_address ||= Spree::Address.default(try_spree_current_user, "bill") + @order.ship_address ||= Spree::Address.default(try_spree_current_user, "ship") if @order.checkout_steps.include?('delivery') end def before_delivery diff --git a/frontend/app/controllers/spree/content_controller.rb b/frontend/app/controllers/spree/content_controller.rb index d8d104516e1..cc96ce901f9 100644 --- a/frontend/app/controllers/spree/content_controller.rb +++ b/frontend/app/controllers/spree/content_controller.rb @@ -13,7 +13,7 @@ def show end def cvv - render :layout => false + render :layout => "minimal" end def fire_visited_path diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index ba82b3ec78b..372e35021cb 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -12,6 +12,10 @@ class OrdersController < Spree::StoreController before_filter :apply_coupon_code, only: :update skip_before_filter :verify_authenticity_token + before_action -> { current_order.update_cart_info if current_order } + + helper Spree::CheckoutHelper + def show @order = Order.find_by_number!(params[:id]) end @@ -44,6 +48,7 @@ def populate populator = Spree::OrderPopulator.new(current_order(create_order_if_necessary: true), current_currency) if populator.populate(params[:variant_id], params[:quantity]) + flash[:notice] = Spree.t(:added_to_cart) respond_with(@order) do |format| format.html { redirect_to cart_path } end From 0f2bebf9be086f58763a6c7fa85b43b3d4c09374 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Fri, 15 Aug 2014 11:02:05 +0200 Subject: [PATCH 04/16] include all fixes for order handling --- core/app/models/spree/order.rb | 74 ++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index b7dc211fa32..25cf7548876 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -5,7 +5,8 @@ module Spree class Order < Spree::Base include Spree::Order::Checkout include Spree::Order::CurrencyUpdater - + include ActionView::Helpers::TextHelper + checkout_flow do go_to_state :address go_to_state :delivery @@ -18,6 +19,7 @@ class Order < Spree::Base attr_reader :coupon_code attr_accessor :temporary_address + if Spree.user_class belongs_to :user, class_name: Spree.user_class.to_s belongs_to :created_by, class_name: Spree.user_class.to_s @@ -55,6 +57,10 @@ def states end end + state_machine do + before_transition any => any, do: :update_cart_info + end + accepts_nested_attributes_for :line_items accepts_nested_attributes_for :bill_address accepts_nested_attributes_for :ship_address @@ -65,8 +71,8 @@ def states before_validation :set_currency before_validation :generate_order_number, on: :create before_validation :clone_billing_address, if: :use_billing? - attr_accessor :use_billing + before_validation :mirror_phone before_create :create_token before_create :link_by_email @@ -77,6 +83,9 @@ def states validates :number, uniqueness: true validate :has_available_shipment + validates :terms_of_service, acceptance: {accept: true, allow_nil: false}, if: :require_terms_acceptance + + make_permalink field: :number delegate :update_totals, :persist_totals, :to => :updater @@ -115,6 +124,35 @@ def self.register_update_hook(hook) self.update_hooks.add(hook) end + # clear cart, tax and shipping info and recalculate + # this way a user can change her address and the free shipping + # is applied correctly (and adjust the cart) + # + def update_cart_info + ensure_updated_shipments + # clear shipments and start over + + #create tax adjusments + create_tax_charge! + + # create shipments, deletes adjusments + create_proposed_shipments + + # per default use the first shipping method + if shipments.any? && shipments.first.shipping_rates.any? + shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.sample + end + + # update shippment costs + set_shipments_cost + refresh_shipment_rates + + apply_free_shipping_promotions + + update_adjustments_on_payment_change + end + + def all_adjustments Adjustment.where("order_id = :order_id OR (adjustable_id = :order_id AND adjustable_type = 'Spree::Order')", order_id: self.id) @@ -174,6 +212,33 @@ def completed? completed_at.present? end + def require_terms_acceptance + return true unless new_record? or ['cart'].include?(state) + end + + def require_email + return true unless new_record? or ['cart'].include?(state) + end + + def mirror_phone + if ship_address.present? && bill_address.present? + ship_address.phone = bill_address.phone + end + end + + def payed? + self.payments.where.not("state" => "invalid").any? do |p| + p.state == "completed" + end + end + + def save_user_address(user) + if user.present? + user.ship_address = self.ship_address if self.ship_address.valid? + user.bill_address = self.bill_address if self.bill_address.valid? + end + end + # Indicates whether or not the user is allowed to proceed to checkout. # Currently this is implemented as a check for whether or not there is at # least one LineItem in the Order. Feel free to override this logic in your @@ -315,7 +380,10 @@ def name end def can_ship? - self.complete? || self.resumed? || self.awaiting_return? || self.returned? + # self.complete? || self.resumed? || self.awaiting_return? || self.returned? + # FR: Fix bug in admin: Shipments are stuck in delivery state + # and cant be shipped + self.delivery? || self.complete? || self.resumed? || self.awaiting_return? || self.returned? end def credit_cards From aa72e81c4154b4f62c39f5b34775a2f42e5336ba Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Fri, 15 Aug 2014 13:54:03 +0200 Subject: [PATCH 05/16] fix use_billing, this is saved in the db --- core/app/models/spree/order.rb | 9 +++++---- frontend/app/controllers/spree/checkout_controller.rb | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 25cf7548876..5a57229c0b2 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -19,7 +19,6 @@ class Order < Spree::Base attr_reader :coupon_code attr_accessor :temporary_address - if Spree.user_class belongs_to :user, class_name: Spree.user_class.to_s belongs_to :created_by, class_name: Spree.user_class.to_s @@ -61,6 +60,8 @@ def states before_transition any => any, do: :update_cart_info end + + accepts_nested_attributes_for :line_items accepts_nested_attributes_for :bill_address accepts_nested_attributes_for :ship_address @@ -234,8 +235,8 @@ def payed? def save_user_address(user) if user.present? - user.ship_address = self.ship_address if self.ship_address.valid? - user.bill_address = self.bill_address if self.bill_address.valid? + user.ship_address = self.ship_address if self.ship_address && self.ship_address.valid? + user.bill_address = self.bill_address if self.bill_address && self.bill_address.valid? end end @@ -716,7 +717,7 @@ def after_resume end def use_billing? - @use_billing == true || @use_billing == 'true' || @use_billing == '1' + self.use_billing == true end def set_currency diff --git a/frontend/app/controllers/spree/checkout_controller.rb b/frontend/app/controllers/spree/checkout_controller.rb index 3bc5ff3677b..234ff468dfa 100644 --- a/frontend/app/controllers/spree/checkout_controller.rb +++ b/frontend/app/controllers/spree/checkout_controller.rb @@ -7,7 +7,7 @@ class CheckoutController < Spree::StoreController ssl_required before_action -> { store_location } - before_action -> { save_user_addresses } + before_action -> { save_user_addresses } before_filter :load_order_with_lock From b32caf7e4571df21e2ccc1ca31be9c21e5f53220 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Fri, 15 Aug 2014 14:46:49 +0200 Subject: [PATCH 06/16] just redirect to the same page if the POST was via ajax (turbolinks post - shopify branch) --- core/app/models/spree/order.rb | 1 + frontend/app/controllers/spree/orders_controller.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 5a57229c0b2..534f0376a56 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -287,6 +287,7 @@ def update! end def clone_billing_address + return if bill_address.nil? if bill_address and self.ship_address.nil? self.ship_address = bill_address.clone else diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index 372e35021cb..17ac2682375 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -50,6 +50,7 @@ def populate if populator.populate(params[:variant_id], params[:quantity]) flash[:notice] = Spree.t(:added_to_cart) respond_with(@order) do |format| + format.js { redirect_to :back } format.html { redirect_to cart_path } end else From 95c2db4e8f882b33c1a0629ae260b27c8a966836 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Mon, 25 Aug 2014 13:32:01 +0200 Subject: [PATCH 07/16] fix creation of adjustments --- core/app/models/spree/order.rb | 41 ++++++++++--------- .../controllers/spree/checkout_controller.rb | 23 ++++++----- .../controllers/spree/orders_controller.rb | 2 +- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 534f0376a56..410f73834b8 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -56,10 +56,6 @@ def states end end - state_machine do - before_transition any => any, do: :update_cart_info - end - accepts_nested_attributes_for :line_items @@ -125,33 +121,38 @@ def self.register_update_hook(hook) self.update_hooks.add(hook) end + state_machine do + before_transition all => all, do: :update_cart_info + end + # clear cart, tax and shipping info and recalculate # this way a user can change her address and the free shipping # is applied correctly (and adjust the cart) # def update_cart_info - ensure_updated_shipments - # clear shipments and start over + # # create shipments, deletes adjusments + if bill_address && bill_address.valid? + create_proposed_shipments + end - #create tax adjusments - create_tax_charge! - - # create shipments, deletes adjusments - create_proposed_shipments - - # per default use the first shipping method - if shipments.any? && shipments.first.shipping_rates.any? + # # per default use the first shipping method + if shipments.present? && !shipments.any? { |shipment| shipment.shipping_rates.blank? } shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.sample + + # update shippment costs + set_shipments_cost + refresh_shipment_rates end - - # update shippment costs - set_shipments_cost - refresh_shipment_rates + # and free shipping apply_free_shipping_promotions - + + # remove or add cod payment adjustments update_adjustments_on_payment_change - end + + # #create tax adjustments + create_tax_charge! + end def all_adjustments diff --git a/frontend/app/controllers/spree/checkout_controller.rb b/frontend/app/controllers/spree/checkout_controller.rb index 234ff468dfa..a51642887ec 100644 --- a/frontend/app/controllers/spree/checkout_controller.rb +++ b/frontend/app/controllers/spree/checkout_controller.rb @@ -24,12 +24,15 @@ class CheckoutController < Spree::StoreController helper 'spree/orders' - rescue_from Spree::Core::GatewayError, :with => :rescue_from_spree_gateway_error + rescue_from Spree::Core::GatewayError, :with => :rescue_from_spree_gateway_error + + # Updates the order and advances to the next state (when possible.) def update if @order.update_from_params(params, permitted_checkout_attributes, request.headers.env) @order.temporary_address = !params[:save_user_address] +# unless @order.next flash[:error] = @order.errors.full_messages.join("\n") redirect_to checkout_state_path(@order.state) and return @@ -50,18 +53,16 @@ def update private - - - def save_marketing - if params["order"] && params["order"]["accepts_marketing"] - sub = Formrausch::Subscription.create_from_order(current_order) - if sub.valid? - sub.send_to_campaign_monitor(false, ENV["CAMPAIGN_MONITOR_CHECKOUT_LIST_ID"]) + def save_marketing + if params["order"] && params["order"]["accepts_marketing"] + sub = Formrausch::Subscription.create_from_order(current_order) + if sub.valid? + sub.send_to_campaign_monitor(false, ENV["CAMPAIGN_MONITOR_CHECKOUT_LIST_ID"]) + end + @order.accepts_marketing = true + @order.save end - @order.accepts_marketing = true - @order.save end - end private def save_user_addresses current_order.save_user_address(spree_current_user) diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index 17ac2682375..3d91a7e34bb 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -12,7 +12,7 @@ class OrdersController < Spree::StoreController before_filter :apply_coupon_code, only: :update skip_before_filter :verify_authenticity_token - before_action -> { current_order.update_cart_info if current_order } + # before_action -> { current_order.update_cart_info if current_order } helper Spree::CheckoutHelper From 8a358e96e2f6b2c502731573012e04890a967d00 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Tue, 26 Aug 2014 13:22:37 +0200 Subject: [PATCH 08/16] better check if order must be updated, backported checkout_controller changes --- core/app/models/spree/order.rb | 38 ++++++++++++------- .../controllers/spree/checkout_controller.rb | 22 ++++++----- .../controllers/spree/orders_controller.rb | 9 ++++- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 410f73834b8..747a7ed714a 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -131,27 +131,33 @@ def self.register_update_hook(hook) # def update_cart_info # # create shipments, deletes adjusments - if bill_address && bill_address.valid? - create_proposed_shipments - end + create_proposed_shipments - # # per default use the first shipping method - if shipments.present? && !shipments.any? { |shipment| shipment.shipping_rates.blank? } - shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.sample + # per default use the first shipping method + select_a_possible_shipping_rate - # update shippment costs - set_shipments_cost - refresh_shipment_rates - end + # update shippment costs + set_shipments_cost + refresh_shipment_rates # and free shipping - apply_free_shipping_promotions + apply_free_shipping_promotions if shipments_available? # remove or add cod payment adjustments update_adjustments_on_payment_change # #create tax adjustments create_tax_charge! + end + + def select_a_possible_shipping_rate + if shipments_available? + shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.sample + end + end + + def shipments_available? + shipments.present? && !shipments.any? { |shipment| !shipment.valid? || shipment.shipping_rates.blank? } end @@ -215,11 +221,11 @@ def completed? end def require_terms_acceptance - return true unless new_record? or ['cart'].include?(state) + state != 'cart' || !new_record? end def require_email - return true unless new_record? or ['cart'].include?(state) + state != 'cart' || !new_record? end def mirror_phone @@ -419,7 +425,11 @@ def finalize! end def deliver_order_confirmation_email - OrderMailer.confirm_email(self.id).deliver + if ENV["ASYNC_EMAILS"] && defined?(Sidekiq) + Spree::OrderMailer.delay.confirm_email(self.id) + else + OrderMailer.confirm_email(self.id).deliver + end update_column(:confirmation_delivered, true) end diff --git a/frontend/app/controllers/spree/checkout_controller.rb b/frontend/app/controllers/spree/checkout_controller.rb index a51642887ec..17193d2b0c9 100644 --- a/frontend/app/controllers/spree/checkout_controller.rb +++ b/frontend/app/controllers/spree/checkout_controller.rb @@ -6,6 +6,8 @@ module Spree class CheckoutController < Spree::StoreController ssl_required + before_action -> { current_order.update_cart_info if current_order } + before_action -> { store_location } before_action -> { save_user_addresses } @@ -53,19 +55,21 @@ def update private - def save_marketing - if params["order"] && params["order"]["accepts_marketing"] - sub = Formrausch::Subscription.create_from_order(current_order) - if sub.valid? - sub.send_to_campaign_monitor(false, ENV["CAMPAIGN_MONITOR_CHECKOUT_LIST_ID"]) + def save_marketing + if params["order"] && params["order"]["accepts_marketing"] + sub = Formrausch::Subscription.create_from_order(current_order) + if sub.valid? + sub.send_to_campaign_monitor(false, ENV["CAMPAIGN_MONITOR_CHECKOUT_LIST_ID"]) + end + @order.accepts_marketing = true + @order.save end - @order.accepts_marketing = true - @order.save end - end - private def save_user_addresses + def save_user_addresses + if current_order current_order.save_user_address(spree_current_user) + end end def ensure_valid_state diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index 3d91a7e34bb..e637294f729 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -12,7 +12,7 @@ class OrdersController < Spree::StoreController before_filter :apply_coupon_code, only: :update skip_before_filter :verify_authenticity_token - # before_action -> { current_order.update_cart_info if current_order } + before_action :update_cart_and_adjustments, only: :edit helper Spree::CheckoutHelper @@ -88,6 +88,13 @@ def check_authorization private + def update_cart_and_adjustments + if current_order + current_order.state ='cart' + current_order.update_cart_info + end + end + def order_params if params[:order] params[:order].permit(*permitted_order_attributes) From ed7bf312a2cbfa29d8e02e03c99190cc18d40063 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Wed, 27 Aug 2014 12:39:31 +0200 Subject: [PATCH 09/16] set order state to cart before edit/update --- core/app/models/spree/order.rb | 15 ++++++--------- .../app/controllers/spree/orders_controller.rb | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 747a7ed714a..e4cf3a19e87 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -75,12 +75,11 @@ def states before_create :link_by_email before_update :homogenize_line_item_currencies, if: :currency_changed? - validates :email, presence: true, if: :require_email - validates :email, email: true, if: :require_email, allow_blank: true + validates :email, email: true, presence: true, if: :require_on_address_page validates :number, uniqueness: true validate :has_available_shipment - validates :terms_of_service, acceptance: {accept: true, allow_nil: false}, if: :require_terms_acceptance + validates :terms_of_service, acceptance: {accept: true, allow_nil: false}, if: :require_on_address_page make_permalink field: :number @@ -220,12 +219,10 @@ def completed? completed_at.present? end - def require_terms_acceptance - state != 'cart' || !new_record? - end - - def require_email - state != 'cart' || !new_record? + def require_on_address_page + # true unless state == 'cart' || new_record? or ['cart'].include?(state) + return false if state == 'cart' + true end def mirror_phone diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index e637294f729..05adcbb7ad9 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -12,10 +12,10 @@ class OrdersController < Spree::StoreController before_filter :apply_coupon_code, only: :update skip_before_filter :verify_authenticity_token - before_action :update_cart_and_adjustments, only: :edit + before_action :update_cart_and_adjustments, except: 'show' helper Spree::CheckoutHelper - + def show @order = Order.find_by_number!(params[:id]) end From 77ea4ef62d41cd6492a09f2200fe4df1aedabf16 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Mon, 8 Sep 2014 09:33:27 +0200 Subject: [PATCH 10/16] ok why use sample?? --- core/app/models/spree/order.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index e4cf3a19e87..0ecff4df1a8 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -151,7 +151,7 @@ def update_cart_info def select_a_possible_shipping_rate if shipments_available? - shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.sample + shipments.first.selected_shipping_rate_id = shipments.first.shipping_rates.first end end From 99a8220bc703507c65ecaa5dc4440fc82b7873b8 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Wed, 22 Oct 2014 23:58:57 +0200 Subject: [PATCH 11/16] remove validator --- core/app/models/spree/order.rb | 7 +-- core/lib/spree/core/validators/email.rb | 58 ++++++++++++------------- spree.gemspec | 1 + 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 0ecff4df1a8..44ec3b65d0d 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -1,4 +1,3 @@ -require 'spree/core/validators/email' require 'spree/order/checkout' module Spree @@ -6,6 +5,7 @@ class Order < Spree::Base include Spree::Order::Checkout include Spree::Order::CurrencyUpdater include ActionView::Helpers::TextHelper + checkout_flow do go_to_state :address @@ -119,9 +119,9 @@ def self.incomplete def self.register_update_hook(hook) self.update_hooks.add(hook) end - + state_machine do - before_transition all => all, do: :update_cart_info + # before_transition all => all, do: :update_cart_info end # clear cart, tax and shipping info and recalculate @@ -129,6 +129,7 @@ def self.register_update_hook(hook) # is applied correctly (and adjust the cart) # def update_cart_info + puts ")" * 100 # # create shipments, deletes adjusments create_proposed_shipments diff --git a/core/lib/spree/core/validators/email.rb b/core/lib/spree/core/validators/email.rb index 6882be2cce3..51dd4a447ba 100644 --- a/core/lib/spree/core/validators/email.rb +++ b/core/lib/spree/core/validators/email.rb @@ -1,29 +1,29 @@ -# Borrowed from http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/ -# Mentioned in tweet here: https://twitter.com/_sohara/status/177120126083141633 -require 'mail' -class EmailValidator < ActiveModel::EachValidator - def validate_each(record,attribute,value) - unless valid?(value) - record.errors.add(attribute, :invalid, {:value => value}.merge!(options)) - end - end - - def valid?(email) - begin - m = Mail::Address.new(email) - # We must check that value contains a domain and that value is an email address - r = m.domain && m.address == email - t = m.__send__(:tree) - # We need to dig into treetop - # A valid domain must have dot_atom_text elements size > 1 - # user@localhost is excluded - # treetop must respond to domain - # We exclude valid email values like - # Hence we use m.__send__(tree).domain - r &&= (t.domain.dot_atom_text.elements.size > 1) - rescue Exception => e - r = false - end - r - end -end +# # Borrowed from http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/ +# # Mentioned in tweet here: https://twitter.com/_sohara/status/177120126083141633 +# require 'mail' +# class EmailValidator < ActiveModel::EachValidator +# def validate_each(record,attribute,value) +# unless valid?(value) +# record.errors.add(attribute, :invalid, {:value => value}.merge!(options)) +# end +# end +# +# def valid?(email) +# begin +# m = Mail::Address.new(email) +# # We must check that value contains a domain and that value is an email address +# r = m.domain && m.address == email +# t = m.__send__(:tree) +# # We need to dig into treetop +# # A valid domain must have dot_atom_text elements size > 1 +# # user@localhost is excluded +# # treetop must respond to domain +# # We exclude valid email values like +# # Hence we use m.__send__(tree).domain +# r &&= (t.domain.dot_atom_text.elements.size > 1) +# rescue Exception => e +# r = false +# end +# r +# end +# end diff --git a/spree.gemspec b/spree.gemspec index ddea0e86f50..ec58408d258 100644 --- a/spree.gemspec +++ b/spree.gemspec @@ -25,4 +25,5 @@ Gem::Specification.new do |s| s.add_dependency 'spree_frontend', version s.add_dependency 'spree_sample', version s.add_dependency 'spree_cmd', version + s.add_dependency 'email_validator', "~> 1.4.0" end From 9f7e2e389d0e876dba64a2c3370d707e14484618 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Fri, 24 Oct 2014 17:07:09 +0200 Subject: [PATCH 12/16] fix: Spree i18n would not work when class evaling --- core/app/models/spree/line_item.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/app/models/spree/line_item.rb b/core/app/models/spree/line_item.rb index 4d8bc6bcf74..7d286d6078c 100644 --- a/core/app/models/spree/line_item.rb +++ b/core/app/models/spree/line_item.rb @@ -17,7 +17,7 @@ class LineItem < Spree::Base validates :quantity, numericality: { only_integer: true, greater_than: -1, - message: Spree.t('validation.must_be_int') + message: I18n.t('spree.validation.must_be_int') } validates :price, numericality: true validates_with Stock::AvailabilityValidator From 07a8b2b4e7826836f70fe3b75425e4b9b28abbf8 Mon Sep 17 00:00:00 2001 From: Christian Latsch Date: Fri, 7 Nov 2014 14:24:42 +0100 Subject: [PATCH 13/16] calculate order total correctly ;) --- core/app/models/spree/order.rb | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 44ec3b65d0d..5b51f023b1e 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -6,7 +6,7 @@ class Order < Spree::Base include Spree::Order::CurrencyUpdater include ActionView::Helpers::TextHelper - + checkout_flow do go_to_state :address go_to_state :delivery @@ -80,7 +80,7 @@ def states validate :has_available_shipment validates :terms_of_service, acceptance: {accept: true, allow_nil: false}, if: :require_on_address_page - + make_permalink field: :number @@ -119,7 +119,7 @@ def self.incomplete def self.register_update_hook(hook) self.update_hooks.add(hook) end - + state_machine do # before_transition all => all, do: :update_cart_info end @@ -132,7 +132,7 @@ def update_cart_info puts ")" * 100 # # create shipments, deletes adjusments create_proposed_shipments - + # per default use the first shipping method select_a_possible_shipping_rate @@ -142,13 +142,15 @@ def update_cart_info # and free shipping apply_free_shipping_promotions if shipments_available? - + # remove or add cod payment adjustments update_adjustments_on_payment_change # #create tax adjustments create_tax_charge! - end + + update_totals + end def select_a_possible_shipping_rate if shipments_available? @@ -157,7 +159,7 @@ def select_a_possible_shipping_rate end def shipments_available? - shipments.present? && !shipments.any? { |shipment| !shipment.valid? || shipment.shipping_rates.blank? } + shipments.present? && !shipments.any? { |shipment| !shipment.valid? || shipment.shipping_rates.blank? } end @@ -222,7 +224,7 @@ def completed? def require_on_address_page # true unless state == 'cart' || new_record? or ['cart'].include?(state) - return false if state == 'cart' + return false if state == 'cart' true end @@ -239,11 +241,11 @@ def payed? end def save_user_address(user) - if user.present? + if user.present? user.ship_address = self.ship_address if self.ship_address && self.ship_address.valid? user.bill_address = self.bill_address if self.bill_address && self.bill_address.valid? end - end + end # Indicates whether or not the user is allowed to proceed to checkout. # Currently this is implemented as a check for whether or not there is at @@ -388,9 +390,9 @@ def name def can_ship? # self.complete? || self.resumed? || self.awaiting_return? || self.returned? - # FR: Fix bug in admin: Shipments are stuck in delivery state + # FR: Fix bug in admin: Shipments are stuck in delivery state # and cant be shipped - self.delivery? || self.complete? || self.resumed? || self.awaiting_return? || self.returned? + self.delivery? || self.complete? || self.resumed? || self.awaiting_return? || self.returned? end def credit_cards @@ -423,7 +425,7 @@ def finalize! end def deliver_order_confirmation_email - if ENV["ASYNC_EMAILS"] && defined?(Sidekiq) + if ENV["ASYNC_EMAILS"] && defined?(Sidekiq) Spree::OrderMailer.delay.confirm_email(self.id) else OrderMailer.confirm_email(self.id).deliver From 30ae2a755b70778ac28221d7f64b12afa5fecc54 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Thu, 20 Nov 2014 21:09:42 +0100 Subject: [PATCH 14/16] faster! checkout --- core/app/models/spree/order.rb | 34 +++++++++++-------- core/app/models/spree/payment/processing.rb | 3 +- .../controllers/spree/orders_controller.rb | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 5b51f023b1e..7f59af77052 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -120,36 +120,40 @@ def self.register_update_hook(hook) self.update_hooks.add(hook) end - state_machine do - # before_transition all => all, do: :update_cart_info - end + # state_machine do + # # before_transition all => all, do: :update_cart_info + # end # clear cart, tax and shipping info and recalculate # this way a user can change her address and the free shipping # is applied correctly (and adjust the cart) # def update_cart_info - puts ")" * 100 - # # create shipments, deletes adjusments - create_proposed_shipments + if !shipments_available? || state == 'payment' + puts "." * 100 - # per default use the first shipping method - select_a_possible_shipping_rate + # # create shipments, deletes adjusments + create_proposed_shipments - # update shippment costs - set_shipments_cost - refresh_shipment_rates + # per default use the first shipping method + select_a_possible_shipping_rate + + set_shipments_cost + refresh_shipment_rates + end + # update shippment costs # and free shipping apply_free_shipping_promotions if shipments_available? # remove or add cod payment adjustments update_adjustments_on_payment_change - # #create tax adjustments - create_tax_charge! - - update_totals + # lets create a tax adjustments + # i'm not sure we need this so disabled by now + + # create_tax_charge! + # update_totals end def select_a_possible_shipping_rate diff --git a/core/app/models/spree/payment/processing.rb b/core/app/models/spree/payment/processing.rb index e9e4671ebc2..0361f61ef40 100644 --- a/core/app/models/spree/payment/processing.rb +++ b/core/app/models/spree/payment/processing.rb @@ -3,7 +3,8 @@ class Payment < Spree::Base module Processing def process! if payment_method && payment_method.source_required? - if source + binding.pry + if source || (payment_method.respond_to?(:no_source_needed) && payment_method.no_source_needed) if !processing? if payment_method.supports?(source) || token_based? if payment_method.auto_capture? diff --git a/frontend/app/controllers/spree/orders_controller.rb b/frontend/app/controllers/spree/orders_controller.rb index 05adcbb7ad9..24271af8544 100644 --- a/frontend/app/controllers/spree/orders_controller.rb +++ b/frontend/app/controllers/spree/orders_controller.rb @@ -12,7 +12,7 @@ class OrdersController < Spree::StoreController before_filter :apply_coupon_code, only: :update skip_before_filter :verify_authenticity_token - before_action :update_cart_and_adjustments, except: 'show' + before_action :update_cart_and_adjustments, except: ['show', 'populate'] helper Spree::CheckoutHelper From 417a767d47be9f2e6883a898d1f954d11fb96605 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Thu, 20 Nov 2014 21:40:43 +0100 Subject: [PATCH 15/16] pry DSAJDHAS --- core/app/models/spree/payment/processing.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/app/models/spree/payment/processing.rb b/core/app/models/spree/payment/processing.rb index 0361f61ef40..7c7113f5120 100644 --- a/core/app/models/spree/payment/processing.rb +++ b/core/app/models/spree/payment/processing.rb @@ -3,8 +3,7 @@ class Payment < Spree::Base module Processing def process! if payment_method && payment_method.source_required? - binding.pry - if source || (payment_method.respond_to?(:no_source_needed) && payment_method.no_source_needed) + if source if !processing? if payment_method.supports?(source) || token_based? if payment_method.auto_capture? From d44b7a6e14ebfb7472dd124ee5846136c190e288 Mon Sep 17 00:00:00 2001 From: Thomas Winkler Date: Wed, 26 Nov 2014 12:07:25 +0100 Subject: [PATCH 16/16] update tax and total price --- core/app/models/spree/order.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 7f59af77052..f9db43a66a3 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -149,11 +149,7 @@ def update_cart_info # remove or add cod payment adjustments update_adjustments_on_payment_change - # lets create a tax adjustments - # i'm not sure we need this so disabled by now - - # create_tax_charge! - # update_totals + update_totals end def select_a_possible_shipping_rate