Last active
October 13, 2015 17:23
-
-
Save mquan/724aeffd2769680f0b34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PurchaseAuditor | |
def self.get_effective_purchased_amount(txn, purchased_balance) | |
if txn.finalized? | |
effective_amount = if txn.purchased_amount.nil? || txn.purchased_amount < 0 | |
[txn.purchased_amount || txn.amount, -purchased_balance].max | |
elsif txn.purchased_amount == 0 | |
0 | |
elsif txn.purchased_amount > 0 | |
if ["Purchase", "CreditBuyOrder"].include?(txn.source_type) | |
txn.purchased_amount | |
else | |
purchased_diff = Transaction.where(owner_id: txn.owner_id, owner_type: "User").finalized.where("transactions.purchased_amount IS NOT NULL AND transactions.purchased_amount != transactions.effective_purchased_amount").where("transactions.finalized_at < ? or (transactions.finalized_at = ? and transactions.id < ?)", txn.finalized_at, txn.finalized_at, txn.id).sum("(transactions.purchased_amount - transactions.effective_purchased_amount)") | |
[purchased_diff + txn.purchased_amount, 0].max | |
end | |
end | |
txn.update_column(:effective_purchased_amount, effective_amount) | |
effective_amount | |
end | |
end | |
def self.audit_purchased_amount(user) | |
tag_map = { "initial_refund" => "initial", "fee_refund" => "fee", "reversal" => ["initial", "upgrade"] } | |
purchased_balance = 0 | |
user.transactions.where("source_type NOT IN (?)", ["CreditDeposit", "CreditSellOrder", "Referral"]).order(:finalized_at, :id).each do |txn| | |
# pre-process unset purchased_amount (these are dependent on original effective purchased amount) | |
puts txn.id | |
if txn.source_type == "Auction" | |
auction = txn.source | |
if txn.owner_id == auction.winner_id # is auction winner | |
# when winner gets refunded | |
if txn.amount > 0 | |
# this has to be done while calculation is going on. | |
if original_txn = txn.source.transactions.finalized.owned_by(user).where("amount < 0 and transactions.finalized_at <= ?", txn.finalized_at).order(:id).last | |
txn.update_column(:purchased_amount, -original_txn.effective_purchased_amount) | |
else | |
txn.update_column(:purchased_amount, 0) | |
end | |
elsif txn.purchased_amount == 0 | |
txn.update_column(:purchased_amount, nil) | |
end | |
end | |
elsif txn.source_type == "Ticket" | |
if txn.amount > 0 | |
if original_txn = txn.source.transactions.finalized.where("amount < 0 and transactions.finalized_at <= ?", txn.finalized_at).order(:id).last | |
txn.update_column(:purchased_amount, -original_txn.effective_purchased_amount) | |
else | |
txn.update_column(:purchased_amount, 0) | |
end | |
end | |
elsif ["GetItNow", "StartBid"].include?(txn.source_type) | |
if txn.amount > 0 | |
# look at tag | |
if original_txn = txn.source.transactions.finalized.where("amount < 0 and transactions.finalized_at <= ? and id < ? and tag in (?)", txn.finalized_at, txn.id, Array.wrap(tag_map[txn.tag])).order(:id).last | |
txn.update_column(:purchased_amount, -original_txn.effective_purchased_amount) | |
else | |
txn.update_column(:purchased_amount, 0) | |
end | |
end | |
end | |
if epa = get_effective_purchased_amount(txn, purchased_balance) | |
purchased_balance += epa | |
end | |
end | |
puts "updating purchased_credits #{user.id}" | |
user.wallet.update_column(:purchased_credits, purchased_balance) | |
end | |
end | |
reruns = {} | |
user_ids = Purchase.group(:user_id).pluck(:user_id) | |
File.open("/home/listia/purchase_status.txt", "w") do |file| | |
user_ids.each_with_index do |user_id, index| | |
if user = User.find_by(id: user_id) | |
file.puts "#{index} processed, current user_id = #{user_id}" if index % 1000 == 0 | |
last_txn = user.transactions.finalized.order(:finalized_at, :id).last | |
PurchaseAuditor.audit_purchased_amount(user) | |
# re audit if there's a transaction finalized while we're auditing this user | |
# technically we can simply run for transactions after last | |
# but we don't have purchased_balance here | |
if last_txn != user.transactions.reload.finalized.order(:finalized_at, :id).last | |
reruns[user.id] = true | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment