Skip to content

Add abandon cart feature, remove cart from mailchimp if remove lineitems #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/models/spree/chimpy/line_item_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Spree::LineItem.class_eval do
after_destroy :notify_mail_chimp

def notify_mail_chimp
Spree::Chimpy.enqueue(:order, order) if order.email.present? && Spree::Chimpy.configured?
end
end
10 changes: 8 additions & 2 deletions app/models/spree/order_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@
end

around_save :handle_cancelation
after_save :handle_mailchimp_cart

def notify_mail_chimp
Spree::Chimpy.enqueue(:order, self) if completed? && Spree::Chimpy.configured?
Spree::Chimpy.enqueue(:order, self) if email.present? && Spree::Chimpy.configured?
end

private
private
def handle_cancelation
canceled = state_changed? && canceled?
yield
notify_mail_chimp if canceled
end

# Email is not available when transit from registration page to address page.
def handle_mailchimp_cart
notify_mail_chimp if email.present? && state == 'address'
end
end
40 changes: 32 additions & 8 deletions lib/spree/chimpy/interface/customer_upserter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ def customer_id_from_eid(mc_eid)
.retrieve(params: { "fields" => "customers.id", "email_address" => email })

data = response["customers"].first
data["id"] if data
#data["id"] if data
if data
update_cutomer_orders(data["id"])
data["id"]
end
rescue Gibbon::MailChimpError => e
nil
end
Expand All @@ -39,26 +43,46 @@ def customer_id_from_eid(mc_eid)
private

def upsert_customer
return unless @order.user_id
customer_id = @order.user_id || "#{@order.email.downcase}"

customer_id = self.class.mailchimp_customer_id(@order.user_id)
customer_id = self.class.mailchimp_customer_id(customer_id)
begin
response = store_api_call
.customers(customer_id)
.retrieve(params: { "fields" => "id,email_address"})
update_cutomer_orders(response) if response.present? && response['id'].present?
rescue Gibbon::MailChimpError => e
# Customer Not Found, so create them
response = store_api_call
.customers
.create(body: {
id: customer_id,
email_address: @order.email.downcase,
opt_in_status: Spree::Chimpy::Config.subscribe_to_list || false
})
.create(body: data.merge(id: customer_id))
end
customer_id
end

def update_cutomer_orders(customer)
store_api_call
.customers(customer['id'])
.update(body: data.merge(id: customer['id']))
end

def data
{
email_address: @order.email.downcase,
opt_in_status: true,
orders_count: customer_orders.count,
total_spent: total_spent
}
end

def total_spent
customer_orders.pluck(:total).sum.round(2)
end

def customer_orders
Spree::Order.complete.where('email=?', @order.email)
end

end
end
end
97 changes: 82 additions & 15 deletions lib/spree/chimpy/interface/order_upserter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def upsert
private

def perform_upsert
data = order_hash
log "Adding order #{@order.number} for #{data[:customer][:id]} with campaign #{data[:campaign_id]}"
data = api_data
log "Adding order/cart #{@order.number} for #{data[:customer][:id]} with campaign #{data[:campaign_id]}"
begin
find_and_update_order(data)
rescue Gibbon::MailChimpError => e
Expand All @@ -32,19 +32,56 @@ def perform_upsert
end
end

def api_data
return cart_hash if @order.state != 'complete'
order_hash
end

def find_and_update_order(data)
# retrieval is checks if the order exists and raises a Gibbon::MailChimpError when not found
response = store_api_call.orders(@order.number).retrieve(params: { "fields" => "id" })
log "Order #{@order.number} exists, updating data"
store_api_call.orders(@order.number).update(body: data)
if @order.state != 'complete'
store_api_call.carts(@order.number).retrieve(params: { "fields" => "id" })
log "Cart #{@order.number} exists, updating data"
if @order.reload.line_items.empty?
remove_cart_from_mailchimp if cart_exist?
else
store_api_call.carts(@order.number).update(body: data)
end
else
store_api_call.orders(@order.number).retrieve(params: { "fields" => "id" })
log "Order #{@order.number} exists, updating data"
store_api_call.orders(@order.number).update(body: data)
end
end

def create_order(data)
store_api_call
.orders
.create(body: data)
if @order.state != 'complete'
url = store_api_call.carts
else
url = store_api_call.orders
remove_cart_from_mailchimp if cart_exist?
CustomerUpserter.new(@order).ensure_customer
end
url.create(body: data)
rescue Gibbon::MailChimpError => e
log "Unable to create order #{@order.number}. [#{e.raw_body}]"
log "Unable to create cart/order #{@order.number}. [#{e.raw_body}]"
end

def cart_exist?
begin
response = store_api_call
.carts(@order.number)
.retrieve(params: { "fields" => "id" })
!response["id"].nil?
rescue Gibbon::MailChimpError => e
log "Cart #{@order.number} Not Found"
false
end
end

def remove_cart_from_mailchimp
response = store_api_call
.carts(@order.number).delete
end

def order_variant_hash(line_item)
Expand All @@ -61,14 +98,9 @@ def order_variant_hash(line_item)
def order_hash
source = @order.source

lines = @order.line_items.map do |line|
# MC can only associate the order with a single category: associate the order with the category right below the root level taxon
order_variant_hash(line)
end

data = {
id: @order.number,
lines: lines,
lines: order_lines,
order_total: @order.total.to_f,
financial_status: @order.payment_state || "",
fulfillment_status: @order.shipment_state || "",
Expand All @@ -88,6 +120,41 @@ def order_hash

data
end

def order_lines
@order.line_items.map do |line|
# MC can only associate the order with a single category: associate the order with the category right below the root level taxon
order_variant_hash(line)
end
end

def cart_hash
source = @order.source
data = {
id: @order.number,
lines: order_lines,
order_total: @order.total.to_f,
currency_code: @order.currency,
tax_total: @order.try(:included_tax_total).to_f + @order.try(:additional_tax_total).to_f,
checkout_url: checkout_url,
customer: {
id: customer_id
}
}

if source
data[:campaign_id] = source.campaign_id
end

data
end

def checkout_url
URI::HTTP.build({
host: Rails.application.routes.default_url_options[:host],
:path => "/cart"}
).to_s
end
end
end
end
6 changes: 5 additions & 1 deletion lib/spree_chimpy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ def perform(payload)

case event
when :order
orders.sync(object)
if object.canceled?
orders.remove(object)
else
orders.sync(object)
end
when :subscribe
list.subscribe(object.email, merge_vars(object), customer: object.is_a?(Spree.user_class))
when :unsubscribe
Expand Down