Checkout: Prefill is_business heuristically (Z#23126061) (#3533)

This commit is contained in:
Mira
2023-08-24 17:06:47 +02:00
committed by GitHub
parent 21864885cb
commit 9ba3227837
2 changed files with 42 additions and 8 deletions

View File

@@ -62,27 +62,27 @@ class NamespacedCache:
prefix = int(time.time())
self.cache.set(self.prefixkey, prefix)
def set(self, key: str, value: str, timeout: int=300):
def set(self, key: str, value: any, timeout: int=300):
return self.cache.set(self._prefix_key(key), value, timeout)
def get(self, key: str) -> str:
def get(self, key: str) -> any:
return self.cache.get(self._prefix_key(key, known_prefix=self._last_prefix))
def get_or_set(self, key: str, default: Callable, timeout=300) -> str:
def get_or_set(self, key: str, default: Callable, timeout=300) -> any:
return self.cache.get_or_set(
self._prefix_key(key, known_prefix=self._last_prefix),
default=default,
timeout=timeout
)
def get_many(self, keys: List[str]) -> Dict[str, str]:
def get_many(self, keys: List[str]) -> Dict[str, any]:
values = self.cache.get_many([self._prefix_key(key) for key in keys])
newvalues = {}
for k, v in values.items():
newvalues[self._strip_prefix(k)] = v
return newvalues
def set_many(self, values: Dict[str, str], timeout=300):
def set_many(self, values: Dict[str, any], timeout=300):
newvalues = {}
for k, v in values.items():
newvalues[self._prefix_key(k)] = v

View File

@@ -39,10 +39,13 @@ from decimal import Decimal
from django.conf import settings
from django.contrib import messages
from django.core.cache import caches
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.core.signing import BadSignature, loads
from django.core.validators import EmailValidator
from django.db.models import F, Q
from django.db import models
from django.db.models import Count, F, Q, Sum
from django.db.models.functions import Cast
from django.http import HttpResponseNotAllowed, JsonResponse
from django.shortcuts import redirect
from django.utils import translation
@@ -62,12 +65,14 @@ from pretix.base.services.cart import (
)
from pretix.base.services.memberships import validate_memberships_in_order
from pretix.base.services.orders import perform_order
from pretix.base.services.tasks import EventTask
from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.signals import validate_cart_addons
from pretix.base.templatetags.money import money_filter
from pretix.base.templatetags.phone_format import phone_format
from pretix.base.templatetags.rich_text import rich_text_snippet
from pretix.base.views.tasks import AsyncAction
from pretix.celery_app import app
from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.forms.checkout import (
ContactForm, InvoiceAddressForm, InvoiceNameForm, MembershipForm,
@@ -802,7 +807,9 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
@cached_property
def invoice_form(self):
wd = self.cart_session.get('widget_data', {})
if not self.invoice_address.pk:
if self.invoice_address.pk:
wd_initial = {}
elif wd:
wd_initial = {
'name_parts': {
k[21:].replace('-', '_'): v
@@ -817,7 +824,9 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
'country': wd.get('invoice-address-country', ''),
}
else:
wd_initial = {}
wd_initial = {
'is_business': self._get_is_business_heuristic(),
}
initial = dict(wd_initial)
if self.cart_customer:
@@ -1133,6 +1142,31 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
ctx['profiles_data'] = profiles_list
return ctx
def _get_is_business_heuristic(self):
key = 'checkout_heuristic_is_business:' + str(self.event.pk)
cached_result = caches['default'].get(key)
if cached_result is None:
if caches['default'].add(key, False, timeout=10): # return False while query is running
QuestionsStep._update_is_business_heuristic.apply_async(args=(self.event.pk,))
return False
else:
return cached_result
@staticmethod
@app.task(base=EventTask)
def _update_is_business_heuristic(event):
result = InvoiceAddress.objects.filter(order__event=event).aggregate(
total=Count('*'), business=Sum(Cast('is_business', output_field=models.IntegerField())))
if result['total'] < 100:
result = InvoiceAddress.objects.filter(order__event__organizer=event.organizer).aggregate(
total=Count('*'), business=Sum(Cast('is_business', output_field=models.IntegerField())))
if result['business'] and result['total']:
is_business = result['business'] / result['total'] >= 0.6
else:
is_business = False
key = 'checkout_heuristic_is_business:' + str(event.pk)
caches['default'].set(key, is_business, timeout=12 * 3600) # 12 hours
class PaymentStep(CartMixin, TemplateFlowStep):
priority = 200