module Piggybak class Order < ActiveRecord::Base has_many :line_items, :inverse_of => :order has_many :payments, :inverse_of => :order has_many :shipments, :inverse_of => :order has_many :credits, :inverse_of => :order belongs_to :billing_address, :class_name => "Piggybak::Address" belongs_to :shipping_address, :class_name => "Piggybak::Address" belongs_to :user accepts_nested_attributes_for :billing_address, :allow_destroy => true accepts_nested_attributes_for :shipping_address, :allow_destroy => true accepts_nested_attributes_for :shipments, :allow_destroy => true accepts_nested_attributes_for :line_items, :allow_destroy => true accepts_nested_attributes_for :payments # test :allow_destroy validates_presence_of :status validates_presence_of :email validates_presence_of :phone validates_presence_of :total validates_presence_of :total_due validates_presence_of :tax_charge validates_presence_of :created_at before_validation :set_defaults after_validation :update_totals before_save :process_payments, :update_status def process_payments has_errors = false self.payments.each do |payment| if(!payment.process) has_errors = true end end self.total_due = self.total payments.each do |payment| self.total_due -= payment.total end !has_errors end def details if !self.new_record? subtotal = self.line_items.inject(0) { |subtotal, li| subtotal + li.total } shipping = self.shipments.inject(0) { |shipping, shipment| shipping + shipment.total } return "Status: #{self.status}
" + "Subtotal: $#{"%.2f" % subtotal}
" + "Shipping: $#{"%.2f" % shipping}
" + "Tax: $#{"%.2f" % self.tax_charge}
" + "Due: $#{"%.2f" % self.total_due}
" + "Created at: #{self.created_at.strftime("%m-%d-%Y")}
" #details here" else return "New Order" end end def add_line_items(cart) cart.update_quantities cart.items.each do |item| line_item = Piggybak::LineItem.new({ :variant_id => item[:variant].id, :total => item[:variant].price*item[:quantity], :quantity => item[:quantity] }) self.line_items << line_item end end def set_defaults self.created_at ||= Time.now self.status ||= "new" self.total = 0 self.total_due = 0 self.tax_charge = 0 self.line_items.each do |line_item| line_item.total = line_item.variant.price * line_item.quantity end end def update_totals self.total = 0 self.line_items.each do |line_item| self.total += line_item.total end self.tax_charge = TaxMethod.calculate_tax(self) self.total += self.tax_charge shipments.each do |shipment| if shipment.new_record? calculator = shipment.shipping_method.klass.constantize shipment.total = calculator.rate(shipment.shipping_method, self) end self.total += shipment.total end # Hook in credits, TBD credits.each do |credit| self.total -= credit.total end self.total = self.total.to_c self.total_due = self.total payments.each do |payment| self.total_due -= payment.total end end def update_status if self.total_due > 0.00 self.status = "payment owed" elsif self.total_due < 0.00 self.status = "credit_owed" else if self.total == 0.00 self.status = "new" elsif self.shipments.all? { |s| s.status == "shipped" } self.status = "shipped" else self.status = "paid" end end end def status_enum ["incomplete", "paid", "shipped"] end def avs_address { :address1 => self.billing_address.address1, :city => self.billing_address.city, :state => self.billing_address.state, :zip => self.billing_address.zip, :country => "US" } end def admin_label "Order ##{self.id}" end end end