Class: MerchantSidekick::PurchaseOrder
- Defined in:
- lib/merchant_sidekick/purchase_order.rb
Instance Method Summary collapse
-
#additional_line_items(items) ⇒ Object
process additional line items before build invoice.
-
#authorize(payment_object, options = {}) ⇒ Object
Authorizes a payment over the order gross amount.
- #authorize_recurring(authorization = nil, options = {}) ⇒ Object
-
#build_addresses(options = {}) ⇒ Object
Builds billing, shipping and origin addresses.
- #build_invoice ⇒ Object
-
#capture(options = {}) ⇒ Object
Captures the amount of the order that was previously authorized If the capture amount.
-
#duplicate_line_items ⇒ Object
make sure we get a copy of the line items.
-
#last_unsaved_invoice ⇒ Object
returns last unsaved invoice.
-
#pay(payment_object, options = {}) ⇒ Object
Pay the order and generate invoice.
-
#pay_recurring(authorization = nil, options = {}) ⇒ Object
E.g.
-
#payment_options(options = {}) ⇒ Object
returns a hash of additional merchant data passed to authorize you want to pass in the following additional options.
-
#purchase_order? ⇒ Boolean
yes, i am a purchase order!.
-
#recurring(payment_object, options = {}) ⇒ Object
E.g.
-
#refund(options = {}) ⇒ Object
refunds a previously paid order Note: :card_number must be supplied.
-
#to_invoice_class_name ⇒ Object
used in build_invoice to determine which type of invoice.
-
#void(options = {}) ⇒ Object
Voids a previously authorized invoice payment and sets the status to cancel Usage: void(options = {}).
Methods inherited from Order
#enter_approved, #enter_canceled, #enter_created, #enter_pending, #enter_received, #enter_refunded, #enter_returned, #enter_returning, #enter_shipped, #enter_shipping, #evaluate, #exit_approved, #exit_canceled, #exit_created, #exit_pending, #exit_received, #exit_refunded, #exit_returned, #exit_returning, #exit_shipped, #exit_shipping, generate_unique_id, #gross_total, #guard_approve_payment_from_pending, #guard_cancel_from_created, #guard_cancel_from_pending, #guard_confirm_reception_from_shipped, #guard_confirm_return_from_returning, #guard_confirm_return_from_shipped, #guard_process_payment_from_created, #guard_process_shipping_from_approved, #guard_refund_from_returned, #guard_reject_from_received, #guard_ship_from_shipping, #invoice, #items_count, #line_items_count, #net_total, #number, #push, #tax_total, #total
Instance Method Details
#additional_line_items(items) ⇒ Object
process additional line items before build invoice
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 280 def additional_line_items(items) # add line items if !items.blank? if items.is_a?(Array) && items.all? {|i| i.is_a?(MerchantSidekick::ShoppingCart::LineItem)} duped = self.buyer.dup order = duped.purchase items @additional_line_items = order.line_items elsif items.is_a?(Array) && items.all? {|i| i.is_a?(LineItem)} @additional_line_items = items elsif items.is_a?(Array) && items.all? {|i| i.is_a?(Product)} # array of products duped = self.buyer.dup cart = Cart.new(self.currency) items.each {|product| cart.add(product)} order = duped.purchase cart.line_items @additional_line_items = order.line_items end end end |
#authorize(payment_object, options = {}) ⇒ Object
Authorizes a payment over the order gross amount
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 7 def (payment_object, ={}) defaults = {:order_id => number} = defaults.merge().symbolize_keys transaction do buyer.send(:before_authorize_payment, self) if buyer && buyer.respond_to?(:before_authorize_payment) self.build_addresses self.build_invoice unless self.last_unsaved_invoice = self.last_unsaved_invoice.(payment_object, ) if .success? process_payment! end buyer.send(:after_authorize_payment, self) if buyer && buyer.respond_to?(:after_authorize_payment) end end |
#authorize_recurring(authorization = nil, options = {}) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 161 def (=nil, ={}) # recurring payment recurring_payment = if .nil? self.payments.recurring.find(:all, :order => "payments.id ASC").last elsif .is_a?(Payment) && self.payments.include?() else self.payments.find(:first, :conditions => ["payments.id = ? OR payments.reference = ? OR payments.uuid = ?", ]) end # recurring expired if !self.pending? || self.purchase_invoices.paid.count > recurring_payment.duration_occurrences raise MerchantSidekick::RecurringPaymentError, "Recurring order #{self.number} expired" end transaction do buyer.send(:before_authorize_recurring, self) if buyer && buyer.respond_to?(:before_authorize_recurring) self.additional_line_items([:add_line_items]) self.build_invoice unless self.last_unsaved_invoice = self.last_unsaved_invoice.(recurring_payment, ) if .success? process_payment! end buyer.send(:after_authorize_recurring, self) if buyer && buyer.respond_to?(:after_authorize_recurring) end end |
#build_addresses(options = {}) ⇒ Object
Builds billing, shipping and origin addresses
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 301 def build_addresses(={}) raise ArgumentError.new("No address declared for buyer (#{buyer.class.name} ##{buyer.id}), use e.g. class #{buyer.class.name}; has_address; end") \ unless buyer.respond_to?(:find_default_address) # buyer's billing or default address unless default_billing_address if buyer.respond_to?(:billing_address) && buyer.default_billing_address self.build_billing_address(buyer.default_billing_address.content_attributes) else if buyer_default_address = buyer.find_default_address self.build_billing_address(buyer_default_address.content_attributes) else raise ArgumentError.new( "No billing or default address for buyer (#{buyer.class.name} ##{buyer.id}), use e.g. class #{buyer.class.name}; has_address :billing; end") end end end # buyer's shipping address if buyer.respond_to?(:shipping_address) self.build_shipping_address(buyer.find_shipping_address_or_clone_from( self.billing_address ).content_attributes) unless self.default_shipping_address end self.billing_address.street = "#{Merchant::Sidekick::Version::NAME}" if self.billing_address && self.billing_address.street.to_s =~ /^backend$/ self.shipping_address.street = "#{Merchant::Sidekick::Version::NAME}" if self.shipping_address && self.shipping_address.street.to_s =~ /^backend$/ # seller's billing or default address if seller raise ArgumentError.new("No address for seller (#{seller.class.name} ##{seller.id}), use acts_as_addressable") \ unless seller.respond_to?(:find_default_address) unless default_origin_address if seller.respond_to?(:billing_address) && seller.find_billing_address self.build_origin_address(seller.find_billing_address.content_attributes) else if seller_default_address = seller.find_default_address self.build_origin_address(seller_default_address.content_attributes) end end end end end |
#build_invoice ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 231 def build_invoice new_invoice = self.purchase_invoices.build( :line_items => self.duplicate_line_items, :net_amount => self.net_total, :tax_amount => self.tax_total, :gross_amount => self.gross_total, :buyer => self.buyer, :seller => self.seller, :origin_address => self.origin_address ? self.origin_address.dup : nil, :billing_address => self.billing_address ? self.billing_address.dup : nil, :shipping_address => self.shipping_address ? self.shipping_address.dup : nil ) # set new invoice's line items to invoice we just created new_invoice.line_items.each do |li| if li.new_record? li.invoice = new_invoice else li.update_attribute(:invoice, new_invoice) end end # duplicate addresses new_invoice.build_origin_address(self.origin_address.content_attributes) if self.origin_address new_invoice.build_billing_address(self.billing_address.content_attributes) if self.billing_address new_invoice.build_shipping_address(self.shipping_address.content_attributes) if self.shipping_address new_invoice.evaluate @additional_line_items = nil new_invoice end |
#capture(options = {}) ⇒ Object
Captures the amount of the order that was previously authorized If the capture amount
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 25 def capture(={}) defaults = {:order_id => number} = defaults.merge().symbolize_keys if invoice = self.purchase_invoices.find(:all, :created_at => "invoices.id ASC").last buyer.send(:before_capture_payment, self) if buyer && buyer.respond_to?(:before_capture_payment) capture_result = invoice.capture() if capture_result.success? approve_payment! end buyer.send(:after_capture_payment, self) if buyer && buyer.respond_to?(:after_capture_payment) capture_result end end |
#duplicate_line_items ⇒ Object
make sure we get a copy of the line items
264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 264 def duplicate_line_items result = [] lis = self.line_items lis += @additional_line_items.to_a lis.each do |line_item| li = line_item.dup # Note: use clone in Rails < 3.1 li.sellable = line_item.sellable li.net_amount = line_item.net_amount li.gross_amount = line_item.gross_amount li.order = nil result << li end result end |
#last_unsaved_invoice ⇒ Object
returns last unsaved invoice
223 224 225 226 227 228 229 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 223 def last_unsaved_invoice unless self.purchase_invoices.empty? self.purchase_invoices.last.new_record? ? self.purchase_invoices.last : nil else nil end end |
#pay(payment_object, options = {}) ⇒ Object
Pay the order and generate invoice
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 41 def pay(payment_object, ={}) defaults = { :order_id => number } = defaults.merge().symbolize_keys # fire buyer's before_payment callback buyer.send(:before_payment, self) if buyer && buyer.respond_to?(:before_payment) self.build_addresses self.build_invoice unless self.last_unsaved_invoice payment = self.last_unsaved_invoice.purchase(payment_object, ) if payment.success? process_payment! approve_payment! end save! # fire buyer's after_payment callback buyer.send(:after_payment, self ) if buyer && buyer.respond_to?(:after_payment) payment end |
#pay_recurring(authorization = nil, options = {}) ⇒ Object
E.g.
@order.pay_recurring("c3s34", :add_line_items => @line_items)
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 131 def pay_recurring(=nil, ={}) # recurring payment recurring_payment = if .nil? self.payments.recurring.find(:all, :order => "payments.id ASC").last elsif .is_a?(Payment) && self.payments.include?() else self.payments.find(:first, :conditions => ["payments.id = ? OR payments.reference = ? OR payments.uuid = ?", ]) end # recurring expired if !self.pending? || self.purchase_invoices.paid.count > recurring_payment.duration_occurrences raise MerchantSidekick::RecurringPaymentError, "Recurring order #{self.number} expired" end transaction do buyer.send(:before_pay_recurring, self) if buyer && buyer.respond_to?(:before_pay_recurring) self.additional_line_items([:add_line_items]) self.build_invoice unless self.last_unsaved_invoice = self.last_unsaved_invoice.purchase(recurring_payment, ) if .success? # add next billing due date process_payment! end buyer.send(:after_pay_recurring, self) if buyer && buyer.respond_to?(:before_pay_recurring) end end |
#payment_options(options = {}) ⇒ Object
returns a hash of additional merchant data passed to authorize you want to pass in the following additional options
:ip => ip address of the buyer
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 195 def (={}) { # general :buyer => self.buyer, :seller => self.seller, :payable => self, # active merchant relevant :customer => self.buyer ? "#{self.buyer.name} (#{self.buyer.id})" : nil, :email => self.buyer && self.buyer.respond_to?(:email) ? self.buyer.email : nil, :order_number => self.number, #:invoice => self.number, :merchant => self.seller ? "#{self.seller.name} (#{self.seller.id})" : nil, :currency => self.currency, :billing_address => self.billing_address ? self.billing_address.to_merchant_attributes : nil, :shipping_address => self.shipping_address ? self.shipping_address.to_merchant_attributes : nil }.merge() end |
#purchase_order? ⇒ Boolean
yes, i am a purchase order!
213 214 215 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 213 def purchase_order? true end |
#recurring(payment_object, options = {}) ⇒ Object
E.g.
@order.recurring(@payment, :interval => {:length => 1, :unit => :month},
:duration => {:start_date => Date.today, :occurrences => 999})
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 107 def recurring(payment_object, ={}) defaults = {:order_id => number} = defaults.merge().symbolize_keys self.build_addresses = Payment.class_for(payment_object).recurring( gross_total, payment_object, ()) self.push_payment() if .success? save(false) process_payment! else # we don't want to save the payment and related objects # when the authorization fails # transaction_declined! end end |
#refund(options = {}) ⇒ Object
refunds a previously paid order Note: :card_number must be supplied
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 84 def refund(={}) defaults = { :order_id => number } = defaults.merge().symbolize_keys if (invoice = self.purchase_invoices.find(:all, :created_at => "invoices.id ASC").last) && invoice.paid? # fire buyer's before_refund_payment callback buyer.send(:before_refund_payment, self) if buyer && buyer.respond_to?(:before_refund_payment) refunded_result = invoice.credit() if refunded_result.success? refund! end save! # fire buyer's after_refund_payment callback buyer.send(:after_refund_payment, self) if buyer && buyer.respond_to?(:after_refund_payment) refunded_result end end |
#to_invoice_class_name ⇒ Object
used in build_invoice to determine which type of invoice
218 219 220 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 218 def to_invoice_class_name "MerchantSidekick::PurchaseInvoice" end |
#void(options = {}) ⇒ Object
Voids a previously authorized invoice payment and sets the status to cancel Usage:
void( = {})
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/merchant_sidekick/purchase_order.rb', line 64 def void(={}) defaults = { :order_id => self[:number] } = defaults.merge().symbolize_keys if invoice = self.purchase_invoices.find(:all, :created_at => "invoices.id ASC").last # before_payment buyer.send(:before_void_payment, self ) if buyer && buyer.respond_to?(:before_void_payment) voided_result = invoice.void() if voided_result.success? cancel! end save! # after_void_payment buyer.send(:after_void_payment, self) if buyer && buyer.respond_to?(:after_void_payment) voided_result end end |