Created
December 12, 2014 01:43
-
-
Save braidn/fa6e4d79784b73d7b608 to your computer and use it in GitHub Desktop.
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 | |
Order.instance_eval do | |
def find_by_number(number) | |
order = complete.where(number:number).take | |
order ||= where(number:number).take | |
end | |
def find_by_number!(number) | |
find_by_number(number) | |
end | |
end | |
Order.class_eval do | |
cattr_accessor :env | |
scope :line_item_count_gt, ->(count) { | |
select("#{Spree::Order.table_name}.*"). | |
joins(:line_items). | |
group("#{Spree::Order.table_name}.id"). | |
having("count(#{Spree::LineItem.table_name}.id) > ?", count) | |
} | |
scope :has_promotion, ->(id) { | |
joins(:adjustments).where("#{Spree::Adjustment.table_name}.originator_type = 'Spree::PromotionAction' AND #{Spree::Adjustment.table_name}.originator_id IN (?)", Spree::Promotion.find(id).promotion_actions.map(&:id)) | |
} | |
after_save :set_user_id_on_addresses | |
def self.define_state_machine! | |
self.checkout_steps = {} | |
self.next_event_transitions = [] | |
self.previous_states = [:cart] | |
self.removed_transitions = [] | |
# Build the checkout flow using the checkout_flow defined either | |
# within the Order class, or a decorator for that class. | |
# | |
# This method may be called multiple times depending on if the | |
# checkout_flow is re-defined in a decorator or not. | |
instance_eval(&checkout_flow) | |
klass = self | |
# To avoid a ton of warnings when the state machine is re-defined | |
StateMachine::Machine.ignore_method_conflicts = true | |
# To avoid multiple occurrences of the same transition being defined | |
# On first definition, state_machines will not be defined | |
state_machines.clear if respond_to?(:state_machines) | |
state_machine :state, :initial => :cart, :use_transactions => false, :action => :save_state do | |
klass.next_event_transitions.each { |t| transition(t.merge(:on => :next)) } | |
# Persist the state on the order | |
after_transition do |order, transition| | |
order.state = order.state | |
order.state_changes.create( | |
previous_state: transition.from, | |
next_state: transition.to, | |
name: 'order', | |
user_id: order.user_id | |
) | |
order.save | |
end | |
event :cancel do | |
transition :to => :canceled, :if => :allow_cancel? | |
end | |
event :return do | |
transition :to => :returned, :from => :awaiting_return, :unless => :awaiting_returns? | |
end | |
event :resume do | |
transition :to => :resumed, :from => :canceled, :if => :canceled? | |
end | |
event :authorize_return do | |
transition :to => :awaiting_return | |
end | |
before_transition :from => :cart, :do => :ensure_line_items_present | |
if states[:address] | |
before_transition :from => :address, :do => :create_tax_charge! | |
end | |
if states[:delivery] | |
before_transition :to => :delivery, :do => :create_proposed_shipments | |
before_transition :to => :delivery, :do => :ensure_available_shipping_rates | |
end | |
after_transition :to => :complete, :do => :finalize! | |
after_transition :to => :resumed, :do => :after_resume | |
after_transition :to => :canceled, :do => :after_cancel | |
# ADD CUSTOM TRANSITIONS HERE | |
end | |
end | |
alias_method :save_state, :save | |
def generate_order_number | |
if self.number.blank? | |
next_id = ActiveRecord::Base.connection.select_value("select nextval('spree_orders_id_seq')") | |
self.number = "R#{next_id.to_s.rjust(10, '0')}" | |
end | |
self.number | |
end | |
def tax_total | |
tax_adjustment.try(:amount) || 0 | |
end | |
def tax_adjustment | |
adjustments.find_by(originator_type:'Spree::TaxRate') | |
end | |
# Required for Promotion_Tax.rb Calculator | |
def promotions_total | |
# Find the best promotion to calculate from | |
active_promotion = adjustments.promotion.max_by {|promo| promo.amount.abs} | |
active_promotion.try(:amount).to_f | |
end | |
def set_user_id_on_addresses | |
return if user.nil? | |
[ ship_address, bill_address ].each do |address| | |
next if address.nil? | |
next unless address.save_for_later | |
if user.addresses.any? | |
user.addresses.each do |a| | |
next if address.same? a | |
end | |
end | |
address.try :update_attribute, :user_id, user.id | |
end | |
end | |
def international? | |
shipping_address.country.id != 49 if shipping_address.present? | |
end | |
def process_payments! | |
if pending_payments.any? | |
pending_payments.each do |payment| | |
break if payment_total >= total | |
payment.process! | |
if payment.completed? | |
self.payment_total += payment.amount | |
end | |
end | |
end | |
rescue Core::GatewayError => e | |
result = !!Spree::Config[:allow_checkout_on_gateway_error] | |
errors.add(:base, e.message) and return result | |
end | |
def is_risky? | |
self.payments.where(%{ | |
(avs_response IS NOT NULL and avs_response != '' and avs_response != 'D' and avs_response != 'M' and avs_response != 'Y' and avs_response != 'X') or | |
(cvv_response_code IS NOT NULL and cvv_response_code != 'M') or | |
state = 'failed' | |
}.squish!).uniq.count > 0 | |
end | |
def push_to_hub | |
return unless self.line_items.count > 0 | |
return if self.shipment_state == 'shipped' | |
Spree::Hub::Client.push(serialized_payload) | |
end | |
def serialized_payload | |
ActiveModel::ArraySerializer.new( | |
[self], | |
each_serializer: self.class.hub_serializer.constantize, | |
root: self.completed_at.present? ? self.class.json_root_name : 'carts' | |
).to_json | |
end | |
def refresh_line_item_prices! | |
if completed_at.nil? | |
refreshed_line_items = line_items.select{|li| li.price != li.variant.price } | |
if refreshed_line_items.present? | |
ActiveRecord::Base.transaction do | |
for li in refreshed_line_items | |
li.old_price = li.price | |
li.update_columns price: li.variant.price, updated_at: Time.current | |
end | |
create_tax_charge! | |
update! | |
end | |
return true | |
end | |
end | |
false | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment