Skip to content

Instantly share code, notes, and snippets.

@SylarRuby
Last active August 8, 2017 19:03
Show Gist options
  • Save SylarRuby/9887211f711faff5886401b40424c443 to your computer and use it in GitHub Desktop.
Save SylarRuby/9887211f711faff5886401b40424c443 to your computer and use it in GitHub Desktop.
Spree Checkout Controller
Spree::CheckoutController.class_eval do
before_filter :get_xero
# https://github.com/spree/spree/blob/master/frontend/app/controllers/spree/checkout_controller.rb
# Updates the order and advances to the next state (when possible.)
# Modified to use Xeroizer
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)) && return
end
if @order.completed?
# Getting the customer details
user_address = spree_current_user.bill_address
country_id = user_address.country_id
# Check if this customer already has a xero_customer_id
# If not, assign one after we create a contact in Xero.com
if spree_current_user.xero_customer_id != nil
contact_id = spree_current_user.xero_customer_id
else
# Create new contact in xero.com
contact = @xero.Contact.build(
name: firstname + " " + lastname, # Must be unique in xero!!!!!
first_name: user_address.firstname,
last_name: user_address.lastname,
email_address: spree_current_user.email,
)
contact.add_address(
:type => "STREET",
:line1 => user_address.address1,
:line2 => user_address.address2,
:city => user_address.city,
:postal_code => user_address.zipcode,
:country => Spree::Country.find(country_id).name,
contact_number: user_address.phone
)
contact.save
# Save the xero_customer_id in our database
# and use their xero_customer_id as contact_id
contact_id = contact.contact_id
spree_current_user.update_attributes(xero_customer_id: contact_id)
end
# Build invoice
invoice = @xero.Invoice.build(
:type => "ACCREC",
status: "AUTHORISED",
currency_code: "GBP", # Change to your conuntry code
reference: "Order " + @current_order.number,
:contact => { contact_id: contact_id },
sent_to_contact: false,
date: DateTime.now,
due_date: DateTime.now,
)
# Iterating over the line_items
@current_order.products.each do |product|
# Amount is quantity times price. Integer values
amount = product.line_items.first.quantity * product.line_items.first.price
invoice.add_line_item(
:description => product.name,
:quantity => product.line_items.first.quantity,
:unit_amount => amount,
:account_code => 200
)
end
# Add shopping to line_items but outside the loop!
invoice.add_line_item(
:description => "Postage and packaging",
:quantity => 1,
:unit_amount => @current_order.shipment_total,
:account_code => 200
)
# Save invoice in Xero.com
invoice.save
# Mark invoice as paid
invoice_payment = {
invoice: invoice,
account: { code: '090' },
date: invoice.date,
amount: invoice.amount_due,
payment_type: 'ACCRECPAYMENT'
}
payment = @xero.Payment.build(invoice_payment)
payment.save
# Setting the order to nil (Normal Spree config)
@current_order = nil
flash.notice = Spree.t(:order_processed_successfully)
flash['order_completed'] = true
redirect_to completion_route
else
redirect_to checkout_state_path(@order.state)
end
else
render :edit
end
end
private
def get_xero
# Sleep for 2 seconds every time the rate limit is exceeded.
@xero = Xeroizer::PrivateApplication.new(ENV['DEMO_XERO_CONSUMER_KEY'],
ENV['DEMO_XERO_SECRET_KEY'],
"#{Rails.root}/privatekey.pem", rate_limit_sleep: 2)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment