billing_monthly_cronjob

 1#!/usr/bin/ruby
 2# frozen_string_literal: true
 3
 4require "dhall"
 5require "pg"
 6
 7require_relative "../lib/blather_notify"
 8require_relative "../lib/to_form"
 9
10CONFIG = Dhall.load(<<-DHALL).sync
11	(#{ARGV[0]}) : {
12		sgx_jmp: Text,
13		notify_using: {
14			jid: Text,
15			password: Text,
16			target: Text -> Text,
17			body: Text -> Text -> Text
18		}
19	}
20DHALL
21
22using ToForm
23
24db = PG.connect(dbname: "jmp")
25db.type_map_for_results = PG::BasicTypeMapForResults.new(db)
26db.type_map_for_queries = PG::BasicTypeMapForQueries.new(db)
27
28BlatherNotify.start(
29	CONFIG[:notify_using][:jid],
30	CONFIG[:notify_using][:password]
31)
32
33promises = []
34
35db.exec(
36	<<-SQL
37	SELECT customer_id
38	FROM customer_plans
39	WHERE expires_at <= LOCALTIMESTAMP + '4 days'
40	SQL
41).each do |row|
42	EM.next_tick do
43		promises << BlatherNotify.execute(
44			"customer info",
45			{ q: row["customer_id"] }.to_form(:submit)
46		).then { |iq|
47			BlatherNotify.write_with_promise(BlatherNotify.command(
48				"customer info",
49				iq.sessionid
50			))
51		}.then do |iq|
52			unless iq.form.field("action")
53				next "#{row["customer_id"]} not found"
54			end
55
56			BlatherNotify.write_with_promise(BlatherNotify.command(
57				"customer info",
58				iq.sessionid,
59				action: :complete,
60				form: { action: "bill_plan" }.to_form(:submit)
61			))
62		end
63	end
64end
65
66one = Queue.new
67
68def format(item)
69	if item.respond_to?(:note) && item.note
70		item.note.text
71	elsif item.respond_to?(:to_xml)
72		item.to_xml
73	else
74		item.inspect
75	end
76end
77
78EM.add_timer(0) do
79	EMPromise.all(promises).then(
80		->(all) { one << all },
81		->(err) { one << RuntimeError.new(format(err)) }
82	)
83end
84
85result = one.pop
86
87raise result if result.is_a?(Exception)
88
89result.each do |item|
90	puts format(item)
91end