Skip to content

Instantly share code, notes, and snippets.

@mquan
Last active October 13, 2015 17:23
Show Gist options
  • Save mquan/724aeffd2769680f0b34 to your computer and use it in GitHub Desktop.
Save mquan/724aeffd2769680f0b34 to your computer and use it in GitHub Desktop.
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