~singpolyma/jmp-pay

ref: a56128b7fa5ae6cd587019dd291f02e95cb4811d jmp-pay/bin/billing_monthly_cronjob -rwxr-xr-x 2.0 KiB
a56128b7Stephen Paul Weber Only try to bill if expired for under a month 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/ruby
# frozen_string_literal: true

require "dhall"
require "pg"

require_relative "../lib/blather_notify"
require_relative "../lib/to_form"

CONFIG = Dhall.load(<<-DHALL).sync
	(#{ARGV[0]}) : {
		sgx_jmp: Text,
		notify_using: {
			jid: Text,
			password: Text,
			target: Text -> Text,
			body: Text -> Text -> Text
		}
	}
DHALL

using ToForm

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

BlatherNotify.start(
	CONFIG[:notify_using][:jid],
	CONFIG[:notify_using][:password]
)

def format(item)
	if item.respond_to?(:note) && item.note && item.note.text != ""
		item.note.text
	elsif item.respond_to?(:to_xml)
		item.to_xml
	else
		item.inspect
	end
end

class ExpiringCustomer
	def initialize(customer_id)
		@customer_id = customer_id
	end

	def info
		BlatherNotify.execute(
			"customer info",
			{ q: @customer_id }.to_form(:submit)
		).then do |iq|
			@sessionid = iq.sessionid
			unless iq.form.field("customer_id")
				raise "#{@customer_id} not found"
			end

			iq
		end
	end

	def next
		raise "Call info first" unless @sessionid

		BlatherNotify.write_with_promise(BlatherNotify.command(
			"customer info",
			@sessionid
		))
	end

	def bill_plan
		raise "Call info first" unless @sessionid

		BlatherNotify.write_with_promise(BlatherNotify.command(
			"customer info",
			@sessionid,
			action: :complete,
			form: { action: "bill_plan" }.to_form(:submit)
		))
	end
end

one = Queue.new

EM::Iterator.new(db.exec(
	<<-SQL
	SELECT customer_id
	FROM customer_plans
	WHERE
		expires_at <= LOCALTIMESTAMP + '4 days' AND
		expires_at > LOCALTIMESTAMP - INTERVAL '1 month'
	SQL
), 3).each(nil, -> { one << :done }) do |row, iter|
	customer = ExpiringCustomer.new(row["customer_id"])
	customer.info.then {
		customer.next
	}.then {
		customer.bill_plan
	}.then { |result|
		puts format(result)
		iter.next
	}.catch do |err|
		one << (err.is_a?(Exception) ? err : RuntimeError.new(format(err)))
	end
end

result = one.pop
raise result if result.is_a?(Exception)