Created
January 21, 2014 07:12
-
-
Save imme5150/8535642 to your computer and use it in GitHub Desktop.
Partial payments for shipments in Spree 1.1.0 - only for credit card payments and shipping is applied only to the first shipment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Spree | |
Payment.class_eval do | |
def complete_or_partial_capture!(amount) | |
return false if amount <= 0 || self.state != 'pending' | |
# if it's close to total payment, round up or down to total payment | |
# this is to counteract rounding errors from tax calculations | |
amount = self.amount if ((amount-0.02)..(amount+0.02)).include?(self.amount) | |
# check to make sure there is enough money authorized for this payment | |
return false if amount > self.amount | |
if amount < self.amount # split the payment | |
new_payment = self.dup | |
new_payment.amount = self.amount - amount | |
new_payment.save | |
self.update_attribute(:amount, amount) | |
end | |
if Rails.env.production? | |
self.capture! | |
else | |
self.update_attribute_without_callbacks(:state, 'completed') | |
end | |
rescue Exception => e | |
if e.message && ( | |
e.message.starts_with?('This transaction is locked down') || | |
e.message.starts_with?('This industry type (eCOMMERCE) does not allow a capture greater than the value of the auth') ) | |
return false # This payment was already captured or the order price changed | |
else | |
raise | |
end | |
end | |
private | |
def record_response(response) | |
details = response.doc.to_s if response.respond_to?(:doc) | |
details ||= response.to_yaml | |
details.gsub!(/AccountNum>\d+<\/AccountNum/, 'AccountNum FILTERED /') | |
log_entries.create({:details => details}, :without_protection => true) | |
end | |
end | |
end | |
Spree::Shipment.class_eval do | |
attr_accessor :payment_successful | |
def shipping_cost | |
# shipping cost is for ONLY the first shipment | |
order.shipments.shipped.order(:shipped_at).first == self ? order.ship_total : 0 | |
end | |
def price | |
# create a dummy order to keep track of the line itmes in the current shipment | |
dummy_order = order.dup | |
dummy_order.line_items = order.shipped_line_items( self ) | |
price = dummy_order.line_items.map(&:total).sum | |
price -= dummy_order.line_item_discounts | |
if (tax_rate = order.tax_rate) | |
price += (tax_rate * price).round(2) | |
end | |
price += shipping_cost | |
end | |
private | |
def after_ship | |
update_attribute_without_callbacks :shipped_at, Time.now | |
inventory_units.each &:ship! | |
self.payment_successful = capture_credit_card_payment_if_needed! | |
Spree::OrderMailer.confirm_email(order, false, self).deliver | |
end | |
def capture_credit_card_payment_if_needed! | |
return true unless (payment = order.payments.pending.from_creditcard.first) | |
payment.complete_or_partial_capture!( self.price ) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment