Completed orders require a customer, add association logic

This commit is contained in:
Rob Harrington
2015-05-13 12:32:55 +10:00
parent 1559b4e30a
commit 34f5cfb6b5
4 changed files with 90 additions and 0 deletions

View File

@@ -9,4 +9,12 @@ class Customer < ActiveRecord::Base
validates :enterprise_id, presence: true
scope :of, ->(enterprise) { where(enterprise_id: enterprise) }
before_create :associate_user
private
def associate_user
self.user = user || Spree::User.find_by_email(email)
end
end

View File

@@ -10,11 +10,14 @@ Spree::Order.class_eval do
belongs_to :order_cycle
belongs_to :distributor, :class_name => 'Enterprise'
belongs_to :cart
belongs_to :customer
validates :customer, presence: true, if: :require_customer?
validate :products_available_from_new_distribution, :if => lambda { distributor_id_changed? || order_cycle_id_changed? }
attr_accessible :order_cycle_id, :distributor_id
before_validation :shipping_address_from_distributor
before_validation :associate_customer, unless: :customer_is_valid?
checkout_flow do
go_to_state :address
@@ -260,4 +263,24 @@ Spree::Order.class_eval do
def product_distribution_for(line_item)
line_item.variant.product.product_distribution_for self.distributor
end
def require_customer?
return true unless new_record? or state == 'cart'
end
def customer_is_valid?
return true unless require_customer?
customer.present? && customer.enterprise_id == distributor_id && customer.email == (user.andand.email || email)
end
def associate_customer
email_for_customer = user.andand.email || email
existing_customer = Customer.of(distributor).find_by_email(email_for_customer)
if existing_customer
self.customer = existing_customer
else
new_customer = Customer.create(enterprise: distributor, email: email_for_customer, user: user)
self.customer = new_customer
end
end
end

View File

@@ -0,0 +1,20 @@
require 'spec_helper'
describe Customer, type: :model do
describe 'creation callbacks' do
let!(:user1) { create(:user) }
let!(:user2) { create(:user) }
let!(:enterprise) { create(:distributor_enterprise) }
it "associates an existing user using email" do
c1 = Customer.create(enterprise: enterprise, email: 'some-email-not-associated-with-a-user@email.com')
expect(c1.user).to be_nil
c2 = Customer.create(enterprise: enterprise, email: 'some-email-not-associated-with-a-user@email.com', user: user1)
expect(c2.user).to eq user1
c3 = Customer.create(enterprise: enterprise, email: user2.email)
expect(c3.user).to eq user2
end
end
end

View File

@@ -511,4 +511,43 @@ describe Spree::Order do
end.to enqueue_job ConfirmOrderJob
end
end
describe "associating a customer" do
let(:user) { create(:user) }
let(:distributor) { create(:distributor_enterprise) }
context "when a user has been set on the order" do
let!(:order) { create(:order, distributor: distributor, user: user) }
context "and a customer for order.distributor and order.user.email already exists" do
let!(:customer) { create(:customer, enterprise: distributor, email: user.email) }
it "associates the order with the existing customer" do
order.send(:associate_customer)
expect(order.customer).to eq customer
end
end
context "and a customer for order.distributor and order.user.email does not alread exist" do
let!(:customer) { create(:customer, enterprise: distributor, email: 'some-other-email@email.com') }
it "creates a new customer" do
expect{order.send(:associate_customer)}.to change{Customer.count}.by 1
end
end
end
context "when a user has not been set on the order" do
let!(:order) { create(:order, distributor: distributor, user: nil) }
context "and a customer for order.distributor and order.email already exists" do
let!(:customer) { create(:customer, enterprise: distributor, email: order.email) }
it "creates a new customer" do
order.send(:associate_customer)
expect(order.customer).to eq customer
end
end
context "and a customer for order.distributor and order.email does not alread exist" do
let!(:customer) { create(:customer, enterprise: distributor, email: 'some-other-email@email.com') }
it "creates a new customer" do
expect{order.send(:associate_customer)}.to change{Customer.count}.by 1
end
end
end
end
end