]>
Commit | Line | Data |
---|---|---|
c7bcb9ca MT |
1 | #!/usr/bin/python3 |
2 | ||
3 | import iso3166 | |
c7bcb9ca MT |
4 | import tornado.web |
5 | ||
6 | from . import base | |
7 | ||
8 | class 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¤cy=%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 | ||
142 | class ThankYouHandler(base.BaseHandler): | |
143 | def get(self): | |
144 | self.render("donate/thank-you.html") | |
145 | ||
146 | ||
147 | class ErrorHandler(base.BaseHandler): | |
148 | def get(self): | |
149 | self.render("donate/error.html") |