From: Michael Tremer Date: Fri, 31 Dec 2021 11:58:27 +0000 (+0000) Subject: donate: Add backend for handling organizations X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e5eac7d4d73fefa25f122fc602785defcd998ae;p=ipfire.org.git donate: Add backend for handling organizations Signed-off-by: Michael Tremer --- diff --git a/src/web/donate.py b/src/web/donate.py index 07f9138a..319dac96 100644 --- a/src/web/donate.py +++ b/src/web/donate.py @@ -42,12 +42,25 @@ class DonateHandler(auth.CacheMixin, base.BaseHandler): @base.ratelimit(minutes=15, requests=5) async def post(self): + type = self.get_argument("type") + if not type in ("individual", "organization"): + raise tornado.web.HTTPError(400, "type is of an invalid value: %s" % type) + amount = self.get_argument("amount") currency = self.get_argument("currency", "EUR") frequency = self.get_argument("frequency") - # Collect donor information - donor = { + organization = None + + # Get organization information + if type == "organization": + organization = { + "name" : self.get_argument("organization"), + "vat_number" : self.get_argument("vat_number", None), + } + + # Collect person information + person = { "email" : self.get_argument("email"), "title" : self.get_argument("title"), "first_name" : self.get_argument("first_name"), @@ -66,24 +79,19 @@ class DonateHandler(auth.CacheMixin, base.BaseHandler): # Send everything to Zeiterfassung try: - # Search for person or create a new one - response = await self.backend.zeiterfassung.send_request( - "/api/v1/persons/search", **donor - ) - - if not response: - response = await self.backend.zeiterfassung.send_request( - "/api/v1/persons/create", **donor, **address - ) + # Create a new organization + if organization: + organization = await self._create_organization(organization, address) - # Store person number - person = response.get("number") + # Create a person + person = await self._create_person(person, address, organization) # Create a new order order = await self._create_order(person=person, currency=currency) # Add donation to the order - await self._create_donation(order, frequency, amount, currency) + await self._create_donation(order, frequency, amount, currency, + vat_included=(type == "individual")) # Submit the order needs_payment = await self._submit_order(order) @@ -104,6 +112,76 @@ class DonateHandler(auth.CacheMixin, base.BaseHandler): except Exception: raise + async def _create_organization(self, organization, address): + # Check if we have an existing organization + response = await self.backend.zeiterfassung.send_request( + "/api/v1/organizations/search", **organization, + ) + + # Update details if we found a match + if response: + number = response.get("number") + + # Update name + await self.backend.zeiterfassung.send_request( + "/api/v1/organizations/%s/name" % number, **organization + ) + + # Update VAT number + vat_number = organization.get("vat_number", None) + if vat_number: + await self.backend.zeiterfassung.send_request( + "/api/v1/organizations/%s/vat-number" % number, vat_number=vat_number, + ) + + # Update address + await self.backend.zeiterfassung.send_request( + "/api/v1/organizations/%s/address" % number, **address, + ) + + return number + + # Otherwise we will create a new one + response = await self.backend.zeiterfassung.send_request( + "/api/v1/organizations/create", **organization, **address, + ) + + # Return the organization's number + return response.get("number") + + async def _create_person(self, person, address, organization=None): + """ + Searches for a matching person or creates a new one + """ + # Check if we have an existing person + response = await self.backend.zeiterfassung.send_request( + "/api/v1/persons/search", **person + ) + + # Update details if we found a match + if response: + number = response.get("number") + + # Update name + await self.backend.zeiterfassung.send_request( + "/api/v1/persons/%s/name" % number, **person, + ) + + # Update address + await self.backend.zeiterfassung.send_request( + "/api/v1/persons/%s/address" % number, **address, + ) + + return number + + # If not, we will create a new one + response = await self.backend.zeiterfassung.send_request( + "/api/v1/persons/create", organization=organization, **person, **address + ) + + # Return the persons's number + return response.get("number") + async def _create_order(self, person, currency=None): """ Creates a new order and returns its ID @@ -115,7 +193,8 @@ class DonateHandler(auth.CacheMixin, base.BaseHandler): # Return the order number return response.get("number") - async def _create_donation(self, order, frequency, amount, currency): + async def _create_donation(self, order, frequency, amount, currency, + vat_included=False): """ Creates a new donation """ @@ -133,7 +212,7 @@ class DonateHandler(auth.CacheMixin, base.BaseHandler): # Set the price await self.backend.zeiterfassung.send_request( "/api/v1/orders/%s/products/%s/price" % (order, sku), - price=amount, currency=currency, + price=amount, currency=currency, vat_included=vat_included, ) async def _submit_order(self, order):