]> git.ipfire.org Git - ipfire.org.git/blame - src/web/donate.py
donations: Split API call into many small things
[ipfire.org.git] / src / web / donate.py
CommitLineData
c7bcb9ca
MT
1#!/usr/bin/python3
2
3import iso3166
c7bcb9ca
MT
4import tornado.web
5
6from . import base
7
8class DonateHandler(base.BaseHandler):
9 def get(self):
10 location = self.get_remote_location()
11
12 if location:
13 country = location.country
14 else:
15 country = None
16
17 # Get defaults
b00cc400
MT
18 first_name = self.get_argument("first_name", None)
19 last_name = self.get_argument("last_name", None)
a5f94966 20 amount = self.get_argument_float("amount", None)
c7bcb9ca
MT
21 currency = self.get_argument("currency", None)
22 frequency = self.get_argument("frequency", None)
23
24 # Set default currency
25 if not currency in ("EUR", "USD"):
26 currency = "EUR"
27
28 # Default to USD for the US only
29 if country == "US":
30 currency = "USD"
31
32 # Set default frequency
33 if not frequency in ("one-time", "monthly"):
34 frequency = "one-time"
35
0ba47b0f 36 self.render("donate/donate.html", countries=iso3166.countries,
b00cc400
MT
37 country=country, first_name=first_name, last_name=last_name,
38 amount=amount, currency=currency, frequency=frequency)
c7bcb9ca 39
53a15fe0 40 @base.ratelimit(minutes=15, requests=5)
9fdf4fb7 41 async def post(self):
c7bcb9ca
MT
42 amount = self.get_argument("amount")
43 currency = self.get_argument("currency", "EUR")
44 frequency = self.get_argument("frequency")
45
bd9cc41d
MT
46 # Collect donor information
47 donor = {
c7bcb9ca
MT
48 "email" : self.get_argument("email"),
49 "title" : self.get_argument("title"),
50 "first_name" : self.get_argument("first_name"),
51 "last_name" : self.get_argument("last_name"),
bd9cc41d
MT
52 }
53
54 # Collect company information
55 company_name = self.get_argument("company_name", None)
56
57 # Collect address information
58 address = {
c7bcb9ca
MT
59 "street1" : self.get_argument("street1"),
60 "street2" : self.get_argument("street2", None),
61 "post_code" : self.get_argument("post_code"),
62 "city" : self.get_argument("city"),
63 "state" : self.get_argument("state", None),
64 "country_code" : self.get_argument("country_code"),
65 }
66
bd9cc41d 67 # Send everything to Zeiterfassung
c7bcb9ca 68 try:
bd9cc41d 69 # Search for person or create a new one
9fdf4fb7 70 response = await self.backend.zeiterfassung.send_request(
bd9cc41d
MT
71 "/api/v1/persons/search", **donor
72 )
c7bcb9ca 73
bd9cc41d
MT
74 if not response:
75 response = await self.backend.zeiterfassung.send_request(
76 "/api/v1/persons/create", **donor, **address
77 )
c7bcb9ca 78
bd9cc41d 79 person = response.get("number")
c7bcb9ca 80
bd9cc41d
MT
81 # Fetch properties of this person
82 response = await self.backend.zeiterfassung.send_request(
83 "/api/v1/persons/%s/properties" % person,
84 )
85
86 # Does this person already have an organization?
87 organization = response.get("organization", None)
88
89 # Search for organization or create a new one
90 if not organization and company_name:
91 response = await self.backend.zeiterfassung.send_request(
92 "/api/v1/organizations/search", name=name,
93 )
94
95 # Create a new one if we could not find anything
96 if not response:
97 response = await self.backend.zeiterfassung.send_request(
98 "/api/v1/organizations/create", name=name, **address,
99 )
100
101 organization = response.get("number")
102
103 # Connect organization and person
104 await self.backend.zeiterfassung.send_request(
105 "/api/v1/organizations/%s/persons/add", person=person,
106 )
107
108 donation = {
109 "organization" : organization,
110 "person" : person,
111
112 # $$$
113 "amount" : amount,
114 "currency" : currency,
115
116 # Is this a recurring donation?
117 "recurring" : frequency == "monthly",
118
119 # Add URLs to redirect the user back
120 "success_url" : "https://%s/donate/thank-you" % self.request.host,
121 "error_url" : "https://%s/donate/error" % self.request.host,
122 "back_url" : "https://%s/donate?amount=%s&currency=%s&frequency=%s" %
123 (self.request.host, amount, currency, frequency),
124 }
125
126 # Create donation
127 response = await self.backend.zeiterfassung.send_request(
128 "/api/v1/donations/create/ipfire-project", **donation)
129
130 # Redirect the user to the payment page
131 redirect_url = response.get("redirect_url")
132 if not redirect_url:
133 raise tornado.web.HTTPError(500, "Did not receive a redirect URL")
134
135 self.redirect(redirect_url)
136
137 # XXX handle any problems when Zeiterfassung is unreachable
138 except Exception:
139 raise
c7bcb9ca
MT
140
141
142class ThankYouHandler(base.BaseHandler):
143 def get(self):
144 self.render("donate/thank-you.html")
145
146
147class ErrorHandler(base.BaseHandler):
148 def get(self):
149 self.render("donate/error.html")