22
33module Credits
44 class AppliedPrepaidCreditsService < BaseService
5- def initialize ( invoice :)
5+ def initialize ( invoice :, preview : false )
66 @invoice = invoice
7+ @preview = preview
78
89 super ( nil )
910 end
@@ -20,50 +21,21 @@ def call
2021
2122 ActiveRecord ::Base . transaction do
2223 Customers ::LockService . call ( customer :, scope : :prepaid_credit ) do
23- ordered_remaining_amounts = calculate_amounts_for_fees_by_type_and_bm
24- remaining_invoice_amount = invoice . total_amount_cents
25-
26- wallets . each do |wallet |
27- wallet . reload
28- wallet_fee_transactions = [ ]
29- wallet_targets_array = wallet . wallet_targets . map do |wt |
30- if wt &.billable_metric_id
31- [ "charge" , wt . billable_metric_id ]
32- end
33- end
34- wallet_types_array = wallet . allowed_fee_types
35-
36- ordered_remaining_amounts . each do |fee_key , remaining_amount |
37- next if remaining_amount <= 0
38-
39- next unless applicable_fee? ( fee_key :, targets : wallet_targets_array , types : wallet_types_array , wallet :)
40-
41- used_amount = wallet_fee_transactions . sum { |t | t [ :amount_cents ] }
42- remaining_wallet_balance = wallet . balance_cents - used_amount
43- next if remaining_wallet_balance <= 0
44-
45- transaction_amount = [ remaining_amount , remaining_wallet_balance , remaining_invoice_amount ] . min
46- next if transaction_amount <= 0
47-
48- ordered_remaining_amounts [ fee_key ] -= transaction_amount
49- remaining_invoice_amount -= transaction_amount
50- wallet_fee_transactions << {
51- fee_key : fee_key ,
52- amount_cents : transaction_amount
53- }
54- end
55- total_amount_cents = wallet_fee_transactions . sum { |t | t [ :amount_cents ] }
56- next if total_amount_cents <= 0
24+ # per each wallet we create a single wallet transaction. wallets_transactions is a hash with wallet and total transaction amount
25+ wallets_transactions = calculate_wallet_transactions
26+ if preview
27+ result . wallet_transactions = wallets_transactions
28+ return result
29+ end
5730
58- wallet_transaction = create_wallet_transaction ( wallet , total_amount_cents )
31+ wallets_transactions . each do |wallet , amount_cents |
32+ wallet_transaction = create_wallet_transaction ( wallet , amount_cents )
33+ result . wallet_transactions << wallet_transaction
5934
6035 if wallet . traceable?
6136 WalletTransactions ::TrackConsumptionService . call! ( outbound_wallet_transaction : wallet_transaction )
6237 end
63-
6438 Wallets ::Balance ::DecreaseService . call ( wallet :, wallet_transaction :, skip_refresh : true )
65-
66- result . wallet_transactions << wallet_transaction
6739 end
6840
6941 update_prepaid_credit_amounts ( result . wallet_transactions )
@@ -80,10 +52,53 @@ def call
8052
8153 private
8254
83- attr_accessor :invoice
55+ attr_accessor :invoice , :preview
8456
8557 delegate :customer , to : :invoice
8658
59+ def calculate_wallet_transactions
60+ ordered_remaining_amounts = calculate_amounts_for_fees_by_type_and_bm
61+ remaining_invoice_amount = invoice . total_amount_cents
62+ wallets_transactions = { }
63+
64+ wallets . each do |wallet |
65+ wallet . reload
66+ wallet_fee_transactions = [ ]
67+ wallet_targets_array = wallet . wallet_targets . map do |wt |
68+ if wt &.billable_metric_id
69+ [ "charge" , wt . billable_metric_id ]
70+ end
71+ end
72+ wallet_types_array = wallet . allowed_fee_types
73+ byebug
74+
75+ ordered_remaining_amounts . each do |fee_key , remaining_amount |
76+ next if remaining_amount <= 0
77+ byebug
78+
79+ next unless applicable_fee? ( fee_key :, targets : wallet_targets_array , types : wallet_types_array , wallet :)
80+
81+ used_amount = wallet_fee_transactions . sum { |t | t [ :amount_cents ] }
82+ remaining_wallet_balance = wallet . balance_cents - used_amount
83+ next if remaining_wallet_balance <= 0
84+
85+ transaction_amount = [ remaining_amount , remaining_wallet_balance , remaining_invoice_amount ] . min
86+ next if transaction_amount <= 0
87+
88+ ordered_remaining_amounts [ fee_key ] -= transaction_amount
89+ remaining_invoice_amount -= transaction_amount
90+ wallet_fee_transactions << {
91+ fee_key : fee_key ,
92+ amount_cents : transaction_amount
93+ }
94+ end
95+ total_amount_cents = wallet_fee_transactions . sum { |t | t [ :amount_cents ] }
96+ next if total_amount_cents <= 0
97+ wallets_transactions [ wallet ] = total_amount_cents
98+ end
99+ wallets_transactions
100+ end
101+
87102 def schedule_webhook_notifications ( wallet_transactions )
88103 wallet_transactions . each do |wt |
89104 Utils ::ActivityLog . produce_after_commit ( wt , "wallet_transaction.created" )
@@ -125,8 +140,9 @@ def calculate_prepaid_credit_breakdown(wallet_transactions)
125140
126141 def calculate_amounts_for_fees_by_type_and_bm
127142 remaining = Hash . new ( 0 )
143+ fees = invoice . persisted? ? invoice . fees . includes ( :charge ) : invoice . fees
128144
129- invoice . fees . includes ( :charge ) . find_each do |fee |
145+ fees . each do |fee |
130146 next if fee . sub_total_excluding_taxes_amount_cents == 0
131147
132148 cap = fee . sub_total_excluding_taxes_amount_cents +
@@ -162,6 +178,7 @@ def reconcile_remaining_amounts(ordered_remaining_amounts)
162178
163179 def wallets_already_applied?
164180 return false unless invoice
181+ return false unless invoice . persisted?
165182
166183 WalletTransaction . exists? ( invoice_id : invoice . id , wallet_id : wallets . map ( &:id ) )
167184 end
0 commit comments