Module: Auth::Concerns::Shopping::PaymentConcern

Extended by:
ActiveSupport::Concern
Includes:
ChiefModelConcern, OwnerConcern
Included in:
Shopping::Payment
Defined in:
app/models/auth/concerns/shopping/payment_concern.rb

Overview

NEED A SEPERATE MODEL THAT IMPLEMENTS IT

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#as_json(options = {}) ⇒ Object



625
626
627
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 625

def as_json(options={})
	super(options).merge({:payment_receipt => self.payment_receipt,:cash_change => self.cash_change})
end

#calculate_changeObject

sets the change to be given to the customer @return : returns nothing, just sets the cash_change attribute.



325
326
327
328
329
330
331
332
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 325

def calculate_change
	## by this point in time the cart has already been set, and prepared, so we know the total pending amount. 
	if self.amount > self.cart.cart_pending_balance
		self.cash_change = self.amount - self.cart.cart_pending_balance
	else
		self.cash_change = 0
	end
end

#card_and_cheque_payment_provides_proofObject



611
612
613
614
615
616
617
618
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 611

def card_and_cheque_payment_provides_proof
	## it is not directly possible to create a card / cheque payment as successfull even as an administrator
	## you have to first create an image resource, and it will check for that in this def, to exist
	## so search for an image resource, that has the payment id of this payment.
	## eg , add this error.

	##self.errors.add("payment_type","you have to upload an image of the card mahine receipt/cheque, to approve this payment.")
end

#card_callback(params, &block) ⇒ Object

the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated



356
357
358
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 356

def card_callback(params,&block)
	
end

#cart_not_emptyObject

validation



533
534
535
536
537
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 533

def cart_not_empty
	return if self.refund == true
	self.errors.add(:cart,"cart has to have some items in order to make a payment") if !self.cart.has_items?

end

#cash_callback(params, &block) ⇒ Object

the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated calculate the change make the amount equal to the pending balance if it is excesive.



314
315
316
317
318
319
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 314

def cash_callback(params,&block)
	if self.new_record?
		calculate_change
		self.amount = self.cart.cart_pending_balance if payment_excessive?
	end
end

#check_owner_matchesObject



620
621
622
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 620

def check_owner_matches
	self.errors.add("cart_id","the cart id and payment are being created by different users.") if (owner_matches(self.cart) == false)
end

#cheque_callback(params, &block) ⇒ Object

the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated



335
336
337
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 335

def cheque_callback(params,&block)
	
end

#cheque_or_card_payment_not_excessiveObject

validation



527
528
529
530
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 527

def cheque_or_card_payment_not_excessive
	
	self.errors.add(:amount,"payment is excessive") if payment_excessive? && (is_cheque? || is_card?) && !refund
end

#discount_callback(params, &block) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 381

def discount_callback(params,&block)

	## so now what next ?
	## what about refunds ?
	## and what about discount coupons for companies ?
	## can i handle that right now as well ?
		
	## the callback should fire on create/update, so new_record checking is not required.

	## first check if the discount id exists -> get the discount object.
	
	#begin
	
		self.discount = Auth.configuration.discount_class.constantize.find(discount_id)

		#puts "discount is: #{self.discount}"


		if self.discount.requires_verification == true
			#puts "detected discount requires verification"
			self.payment_status = Auth.configuration.discount_class.constantize.get_payment_status(self,discount_id)
			#puts "the payment status is detected as: #{self.payment_status}"
		else
			## what about floating discount codes?
			## can a user use them repeatedly?
			self.payment_status = Auth.configuration.discount_class.constantize.use_discount(self.discount,self)
		end

		## now also set the payment amount to be equal to the discount amount or the discount percentage whichever works out be greater.
		## first preference is given to check the discount amount.
		
		if self.discount.discount_amount > 0
			self.amount = self.discount.discount_amount
			
		elsif self.discount.discount_percentage > 0
			self.amount = self.cart.cart_pending_balance*(self.discount.discount_percentage/100.0)
		else
			self.amount = 0
		end

		##finally ensure its not more than the cart_pending_balance
		self.amount = self.cart.cart_pending_balance if self.amount > self.cart.cart_pending_balance

	#rescue
	#	self.payment_status = 0
	#end

end

#gateway_callback(params, &block) ⇒ Object

override this method depending upon the gateway that you use.



373
374
375
376
377
378
379
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 373

def gateway_callback(params,&block)
	## if its a new_record we don't do any callback, because the payment doesnt exist to check it .
	## if the user has passed in is_verify_payment, we still don;t do this callback, because 
	return if (self.new_record? || self.is_verify_payment == "true") 

	yield if block_given?
end

#get_cart_nameObject

used in pay_u_money_helper.rb



274
275
276
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 274

def get_cart_name
	self.cart.nil? ? "shopping_cart" : (self.cart.name.nil? ? "shopping_cart" : self.cart.name)
end

#is_approved?Boolean

Returns:

  • (Boolean)


629
630
631
632
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 629

def is_approved?
	puts "the payment status is: #{self.payment_status}"
	self.payment_status == 1
end

#is_card?Boolean

Returns:

  • (Boolean)


286
287
288
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 286

def is_card?
	payment_type && payment_type == "card"
end

#is_cash?Boolean

Returns:

  • (Boolean)


282
283
284
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 282

def is_cash?
	payment_type && payment_type == "cash"
end

#is_cheque?Boolean

Returns:

  • (Boolean)


290
291
292
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 290

def is_cheque?
	payment_type && payment_type == "cheque"
end

#is_disapproved?Boolean

Returns:

  • (Boolean)


638
639
640
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 638

def is_disapproved?
	self.payment_status == 0
end

#is_gateway?Boolean

Returns:

  • (Boolean)


278
279
280
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 278

def is_gateway?
	payment_type && payment_type == "gateway"
end

#is_pending?Boolean

Returns:

  • (Boolean)


634
635
636
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 634

def is_pending?
	self.payment_status.nil?
end

#payment_callback(type, params, &block) ⇒ Object



294
295
296
297
298
299
300
301
302
303
304
305
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 294

def payment_callback(type,params,&block)
	
	if self.refund
		self.send("refund_callback",params,&block) 
	elsif self.discount_id
		self.send("discount_callback",params,&block)
	else
		self.send("#{type}_callback",params,&block) if self.respond_to? "#{type}_callback"
	end

	yield if block_given?
end

#payment_excessive?Boolean

Returns:

  • (Boolean)


307
308
309
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 307

def payment_excessive?
	self.amount > self.cart.cart_pending_balance && self.amount > 0
end

#payment_failedObject



360
361
362
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 360

def payment_failed
	payment_status && payment_status == 0
end

#payment_pendingObject



368
369
370
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 368

def payment_pending
	!payment_status
end

#payment_satisfies_minimum_payment_requirementObject

validation



602
603
604
605
606
607
608
609
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 602

def payment_satisfies_minimum_payment_requirement
	self.cart.prepare_cart
	#puts "the minimum payment amoutn is:"
	#puts self.cart.cart_minimum_payable_amount
	## what if self.cart.payment_stage.
	return if (self.refund == true || self.discount)  
	self.errors.add("amount","payment amount is not sufficient") if (self.cart.cart_minimum_payable_amount.nil? || (self.cart.cart_minimum_payable_amount > self.amount))
end

#payment_successObject



364
365
366
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 364

def payment_success
	payment_status && payment_status == 1
end

#physical_payment?Boolean

Returns:

  • (Boolean)


431
432
433
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 431

def physical_payment?
	is_card? || is_cash? || is_cheque?
end

#refresh_refundObject

basically checks if there is any refund that was accepted after this refund_request was created. then in that case sets this refund as failed. this is basically done because while normally, whenever a refund is accepted, all other pending refunds are updated as failed, but suppose that that operation does not complete and some refunds are left still pending. then in the controller update action, this method is called on the payment.



240
241
242
243
244
245
246
247
248
249
250
251
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 240

def refresh_refund
	
	if self.refund && self.payment_status.nil?
		
		already_accepted_refunds = self.class.where(:refund => true, :payment_status => 1, :updated_at => { :$gte => self.created_at})
		
		if already_accepted_refunds.size > 0
			
			self.refund_failed
		end
	end
end

#refund_approved_if_cart_pending_balance_is_equal_to_refund_amountObject

validation



575
576
577
578
579
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 575

def refund_approved_if_cart_pending_balance_is_equal_to_refund_amount
	if payment_status_changed? && payment_status == 1 && refund
		self.errors.add("payment_status","you cannot authorize a refund since the amount you entered is wrong") if self.cart.cart_pending_balance != self.amount
	end
end

#refund_callback(params, &block) ⇒ Object



340
341
342
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 340

def refund_callback(params,&block)
	
end

#refund_created_or_approved_only_if_balance_is_negativeObject

validation



563
564
565
566
567
568
569
570
571
572
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 563

def refund_created_or_approved_only_if_balance_is_negative
	if refund
		## in case the admin wants to mark a refund as failed.
		if payment_status == 0 && payment_status_changed?
		
		else
			self.errors.add("payment_status","you cannot authorize a refund since the pending balance is positive.") if self.cart.cart_pending_balance >= 0
		end
	end
end

#refund_created_or_approved_only_if_sum_of_discount_payments_does_not_cover_cart_pending_balanceObject

validation



582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 582

def refund_created_or_approved_only_if_sum_of_discount_payments_does_not_cover_cart_pending_balance

	if refund

		## get the approved discount payments

		## then check the sum of those payments.
		discount_sum = self.class.get_sum_of_discount_payments(self.cart_id)

		if self.cart.cart_pending_balance < 0
			if discount_sum > self.cart.cart_pending_balance*-1
				self.errors.add("amount","the discounts you availed, cover the need for the refund.")
			end
		end

	end

end

#refund_failedObject



350
351
352
353
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 350

def refund_failed
	self.amount = 0
	self.payment_status = 0
end

#refund_successObject



344
345
346
347
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 344

def refund_success
	self.amount = self.cart.refund_amount
	self.payment_status = 1
end

#set_cart(cart_id) ⇒ Object

finds the cart that this payment refers to sets it to an attr_accessor called cart prepares the cart(refer to cart concern for a description of this method)



458
459
460
461
462
463
464
465
466
467
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 458

def set_cart(cart_id)	
	
	
	self.cart = Auth.configuration.cart_class.constantize.find(cart_id)

	
	self.cart.prepare_cart
	

end

#set_payment_receiptObject

returns the cart_item ids which were accepted due to this payment. called after_save callback. called in show action of controller. return



257
258
259
260
261
262
263
264
265
266
267
268
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 257

def set_payment_receipt
	#puts "CAME TO SET PAYMENT RECEIPT ------------------------"
	self.payment_receipt = {:current_payment => [], :cart => {}}
	Auth.configuration.cart_item_class.constantize.where(:accepted_by_payment_id => self.id.to_s).each do |c_item|
		puts "THIS ITEM IS C_ITEM: #{c_item.id.to_s}"
		self.payment_receipt[:current_payment] <<  c_item
	end
	set_cart(self.cart_id) if self.cart.nil?
	self.payment_receipt[:cart] = self.cart.prepare_receipt
	#puts self.payment_receipt.to_s
	#puts "finished set payment receipt."
end

#update_cart_items_acceptedObject

is called on payment_status_changed check whether this payment was already registered on the cart as success or failed. and then debit/credit. return : true/false depending on whether all the cart items could be successfully updated or not.



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 473

def update_cart_items_accepted
	
	if payment_status_changed?
		puts "payment status was changed---------------------"
		if payment_status == 1
			puts "PAYMENT STATUS IS 1"
			self.cart.cart_credit+= self.amount
		elsif payment_status == 0 && payment_status_was == 1
			
			self.cart.cart_credit-= self.amount
		else

		end

	
		cart_item_update_results = self.cart.get_cart_items.map{|cart_item| 
			puts "CART ITEM OF THE CART IS FOUND"
			cart_item.signed_in_resource = self.signed_in_resource
			## first all the expected cart items should exist
			## then they should all get saved
			## none of them should be already accepted.
			## if all these conditions are satisfied.
			## then we can say that nothing else has happedn
			## we do an atomic request
			## where(item_id => whatever, accepted => false).set(accepted => true)
			## if this fails for even one, then the payment fails.
			## and all the remaining cart items -> can be refreshed to show that they are not accepted
			## refresh will say -> where(:payment_id => x, and status = acceptd)
			## so if some other payment gets in the way, either it will fail or this will fail, so it works.
			cart_item.set_accepted(self,nil)
		}.compact.uniq
		self.errors.add(:cart,"cart item status could not be updated") if cart_item_update_results[0] == false
		puts "self errors are:"
		puts self.errors.size
	else
		if (payment_status == 0 || payment_status == 1)
			cart_item_update_results = self.cart.get_cart_items.map{|cart_item|
				puts "VALIDATING IT WITH PAYMENT AT NULL."
				puts cart_item.id.to_s 
				cart_item.signed_in_resource = self.signed_in_resource
				res = cart_item.set_accepted(self,nil)
				res
			}			 
		end
	end
end

#verify_paymentObject



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'app/models/auth/concerns/shopping/payment_concern.rb', line 436

def verify_payment


	if self.new_record?
		return nil
	else
		if self.is_verify_payment == "true"
			if self.payment_pending
				return true
			else
				return nil
			end
		else
			return nil
		end
	end
	
end