Merge branch 'invite-rewards'

Stephen Paul Weber created

* invite-rewards:
  Process invite/referral rewards

Change summary

Gemfile                    |  2 
bin/process_invite_rewards | 62 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)

Detailed changes

Gemfile 🔗

@@ -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"

bin/process_invite_rewards 🔗

@@ -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