module ActiveRecord module Acts #:nodoc: module MuckOrder #:nodoc: def self.included(base) base.extend(ClassMethods) end module ClassMethods def acts_as_muck_order(options = {}) include MuckCommerce::OrderMethods include MuckCommerce::CurrencyMethods include MuckCommerce::DiscountMethods belongs_to :orderable, :polymorphic => true has_many :order_transactions, :as => :transactionable, :dependent => :destroy has_many :order_coupons has_many :coupons, :through => :order_coupons named_scope :newest, :order => 'created_at DESC' include ActiveRecord::Acts::MuckOrder::InstanceMethods extend ActiveRecord::Acts::MuckOrder::SingletonMethods end end # class methods module SingletonMethods end # All the methods available to a record that has had acts_as_muck_order specified. module InstanceMethods # Assign a paypal express token to the order def express_token=(token) write_attribute(:express_token, token) if new_record? && !token.blank? details = PAYPAL_EXPRESS_GATEWAY.details_for(token) self.express_payer_id = details.payer_id self.first_name = details.params["first_name"] self.last_name = details.params["last_name"] end end # Authorizes a paypal express checkout. # total_in_cents: The amount to authorize in cents # options: Options to pass to the paypal gatway. For example: # :subtotal => subtotal_in_cents # :handling => handling_in_cents def paypal_express_checkout(total_in_cents, options = {}) options = { :ip => self.ip_address, :token => self.express_token, :payer_id => self.express_payer_id, :order_id => order_number}.merge(options) response = PAYPAL_EXPRESS_GATEWAY.authorize(total_in_cents, options) self.amount = total_in_cents self.save! authorization = OrderTransaction.parse_response(response, I18n.translate('muck.commerce.paypal_express_authorization'), self.amount) self.transactions << authorization response.success? end # This will use the billing information provided along with the amount to run a transaction through # the remote gateway. The resulting transaction will be associated with the order. # # billing_information: Billing information object that contains valid payment information such as a credit card # or ach info. If a remote vault system is enabled such as the Authorize.Net CIM the # billing information object need only provide a valid customer_profile_id and # customer_payment_profile_id # amount: Specified in cents so $19.95 should be specified as 1995 this avoids the potential # problems with rounding errors. # coupon_code: A valid coupon code or array of codes that can potentially discount the order. # options: Options that can be passed through to the remote gateway. def checkout(billing_information, amount, coupon_codes = [], options = {}) purchase = nil success = false purchase_made = false amount = amount.to_i # Just in case this comes in as a string options[:order_id] = order_number raise MuckCommerce::Exceptions::PaymentGatewayError, I18n.translate('muck.commerce.order_amount_less_than_zero_error') if amount <= 0 transaction do coupons, coupon_amount, coupon_override = calculate_discounts(amount, coupon_codes) self.amount = amount - coupon_amount self.coupons << coupons if coupon_override # If the coupon drops the price to 0 then there is no need to run a transaction through the gateway self.orderable = billing_information.billable self.discount = coupon_amount success = true else if MuckCommerce::Configure.cim_enabled? if !billing_information.has_billing_profile? || options[:update_billing_information] response = OrderTransaction.cim_create_update(billing_information.billable, billing_information) raise MuckCommerce::Exceptions::PaymentGatewayError, I18n.translate('muck.commerce.problem_processing_your_order', :message => response.message) unless response.success? end end if GlobalConfig.authorize_orders_first if MuckCommerce::Configure.cim_enabled? purchase = OrderTransaction.cim_authorize(self.amount, billing_information, options) else purchase = OrderTransaction.authorize(self.amount, billing_information, options) end else if MuckCommerce::Configure.cim_enabled? purchase = OrderTransaction.cim_purchase(self.amount, billing_information, options) else purchase = OrderTransaction.purchase(self.amount, billing_information, options) end end success = purchase.success? if success order_transactions.push(purchase) self.orderable = billing_information.billable purchase_made = true else raise MuckCommerce::Exceptions::PaymentGatewayError, I18n.translate('muck.commerce.problem_processing_your_order', :message => purchase.message) end end self.save! end [success, purchase_made, purchase] end def order_number return self.number if !self.number.nil? record = true while record random = Array.new(10){rand(10)}.join record = Order.find(:first, :conditions => ["number = ?", random]) end self.number = random.to_s end end end end end