~singpolyma/jmp-pay

be15310fc6ed41e978576936e21550149559e4c9 — Stephen Paul Weber 2 years ago bb25999
Process invite/referral rewards

Select all unrewarded codes where there are associated transactions to meet the
reward criteria, and insert the rewards to the DB.
2 files changed, 63 insertions(+), 1 deletions(-)

M Gemfile
A bin/process_invite_rewards
M Gemfile => Gemfile +1 -1
@@ 4,7 4,7 @@ source "https://rubygems.org"

gem "blather"
gem "braintree"
gem "dhall"
gem "dhall", ">= 0.5.3.fixed"
gem "em_promise.rb"
gem "money-open-exchange-rates"
gem "pg"

A bin/process_invite_rewards => bin/process_invite_rewards +62 -0
@@ 0,0 1,62 @@
#!/usr/bin/ruby
# frozen_string_literal: true

require "bigdecimal"
require "dhall"
require "pg"

PLANS =
	Dhall::Coder
	.new(safe: Dhall::Coder::JSON_LIKE + [Symbol])
	.load(<<-DHALL, transform_keys: ->(k) { k&.to_sym })
		let Quota = < unlimited | limited: { included: Natural, price: Natural } >
		let Currency = < CAD | USD >
		in
		(#{ARGV[0]}) : List {
			name: Text,
			currency: Currency,
			monthly_price: Natural,
			minutes: Quota,
			messages: Quota
		}
DHALL

db = PG.connect(dbname: "jmp")
db.type_map_for_results = PG::BasicTypeMapForResults.new(db)
db.type_map_for_queries = PG::BasicTypeMapForQueries.new(db)

QUERY = <<~SQL
	SELECT code::TEXT, creator_id, plan_name
	FROM
		invites
		INNER JOIN transactions ON used_by_id = transactions.customer_id
		INNER JOIN customer_plans ON creator_id = customer_plans.customer_id
	WHERE rewarded_at IS NULL AND used_by_id IS NOT NULL AND amount > 0
	GROUP BY used_by_id, code, creator_id, plan_name
	HAVING
		MIN(transactions.created_at) < LOCALTIMESTAMP - '90 days'::interval
		AND
		SUM(transactions.amount) >= 15
SQL

db.transaction do
	db.exec(QUERY).each do |row|
		puts row["code"]
		plan = PLANS.find { |p| p[:name] == row["plan_name"] }
		price = BigDecimal(plan[:monthly_price]) / 10000
		db.exec(<<~SQL, [row["creator_id"], row["code"], price])
			INSERT INTO transactions
				(customer_id, transaction_id, amount, note)
			VALUES
				($1, 'reward_' || $1 || '_for_' || $2, $3, 'Reward for referral ' || $2)
		SQL
		db.exec(<<~SQL, [row["creator_id"]])
			INSERT INTO invites (creator_id) VALUES ($1)
		SQL
		db.exec(<<~SQL, [row["code"]])
			UPDATE invites
			SET rewarded_at=LOCALTIMESTAMP
			WHERE code=$1
		SQL
	end
end