docs: def applyAndAllocate(self,allocatedPrices,tieredTuples,payAtDoor=False):
          '''
          This method takes an initial allocation of prices across events, and
          an identical length list of allocation tuples.  It applies the rule
          specified by this discount, allocates the discount across the listed
          items, and returns both the price and the allocation
          '''
          initial_net_price = sum([x for x in allocatedPrices])
  
          if self.discountType == self.DiscountType.flatPrice:
              # Flat-price for all applicable items (partial application for items which are
              # only partially needed to apply the discount).  Flat prices ignore any previous discounts
              # in other categories which may have been the best, but they only are applied if they are
              # lower than the price that would be feasible by applying those prior discounts alone.
              applicable_price = self.getFlatPrice(payAtDoor) or 0
  
              this_price = applicable_price \
                  + sum([x[0].event.getBasePrice(payAtDoor=payAtDoor) * x[1] if x[1] != 1 else x[0].price for x in tieredTuples])
  
              # Flat prices are allocated equally across all events
              this_allocated_prices = [x * (this_price / initial_net_price) for x in allocatedPrices]
  
          elif self.discountType == self.DiscountType.dollarDiscount:
              # Discount the set of applicable items by a specific number of dollars (currency units)
              # Dollar discounts are allocated equally across all events.
              this_price = initial_net_price - self.dollarDiscount
              this_allocated_prices = [x * (this_price / initial_net_price) for x in allocatedPrices]
  
          elif self.discountType == DiscountCombo.DiscountType.percentDiscount:
              # Percentage off discounts, which may be applied to all items in the cart,
              # or just to the items that were needed to apply the discount
  
              if self.percentUniversallyApplied:
                  this_price = \
                      initial_net_price * (1 - (max(min(self.percentDiscount or 0,100),0) / 100))
                  this_allocated_prices = [x * (this_price / initial_net_price) for x in allocatedPrices]
              else:
                  # Allocate the percentage discount based on the prior allocation from the prior category
                  this_price = 0
                  this_allocated_prices = []
  
                  for idx, val in enumerate(tieredTuples):
                      this_val = (
                          allocatedPrices[idx] *
                          (1 - val[1]) * (1 - (max(min(self.percentDiscount or 0,100),0) / 100)) +
                          allocatedPrices[idx] * val[1]
                      )
                      this_allocated_prices.append(this_val)
                      this_price += this_val
          else:
              raise KeyError(_('Invalid discount type.'))
  
          if this_price < initial_net_price:
              # Ensure no negative prices
              this_price = max(this_price, 0)
              return self.DiscountInfo(self, this_price, initial_net_price - this_price, this_allocated_prices)