]> git.ipfire.org Git - ipfire.org.git/blobdiff - src/web/donate.py
donate: Add backend for handling organizations
[ipfire.org.git] / src / web / donate.py
index 07f9138a87377b24401e9563fad12067062777e2..319dac9664aa22409b4123ab2450f074eb1aee9c 100644 (file)
@@ -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):