-
Hangzhi Yu authoredHangzhi Yu authored
event_registration.py 8.55 KiB
from django.db import transaction, IntegrityError
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.utils.text import slugify
from django.utils.translation import gettext as _
import graphene
from graphene_django import DjangoObjectType
from templated_email import send_templated_mail
from aleksis.apps.postbuero.models import MailAddress
from aleksis.apps.postbuero.schema import MailAddressInputType
from aleksis.core.models import Activity, Person
from aleksis.core.schema.base import PermissionsTypeMixin
from aleksis.core.schema.person import PersonInputType
from aleksis.core.schema.user import UserInputType
from aleksis.core.util.core_helpers import get_site_preferences
from ..models import Event, EventRegistration, Terms, Voucher
class EventRegistrationType(PermissionsTypeMixin, DjangoObjectType):
class Meta:
model = EventRegistration
class PaymentInputType(graphene.InputObjectType):
payment_method = graphene.String(required=True)
voucher_code = graphene.String(required=False)
amount = graphene.Int(required=True)
class EventRegistrationInputType(graphene.InputObjectType):
email = graphene.Field(MailAddressInputType, required=False)
person = graphene.Field(PersonInputType, required=False)
user = graphene.Field(UserInputType, required=False)
school = graphene.String(required=False)
school_place = graphene.String(required=False)
school_class = graphene.String(required=False)
payment = graphene.Field(PaymentInputType, required=False)
medical_information = graphene.String(required=False)
comment = graphene.String(required=False)
additional_fields = graphene.JSONString(required=False)
terms = graphene.JSONString(required=False)
retraction_consent = graphene.Boolean(required=True)
class SendEventRegistrationMutation(graphene.Mutation):
class Arguments:
event = graphene.ID(required=True)
event_registration = EventRegistrationInputType(required=True)
ok = graphene.Boolean()
@transaction.atomic
def mutate(self, info, event: graphene.ID, event_registration: EventRegistrationInputType, **kwargs):
if not event_registration["retraction_consent"]:
raise ValidationError(_("Retraction consent is required"))
event = Event.objects.get(pk=event)
print(event_registration)
email = None
if event_registration["email"] is not None:
try:
_mail_address = MailAddress.objects.create(
local_part=event_registration["email"]["local_part"],
domain=event_registration["email"]["domain"],
)
except IntegrityError:
raise ValidationError(_("Mail address already in use."))
email = str(_mail_address)
elif event_registration["user"] is not None:
email = event_registration["user"]["email"]
# Create user
if event_registration["user"] is not None:
try:
user = User.objects.create(
username=event_registration["user"]["username"],
email=event_registration["user"]["email"],
)
except IntegrityError:
raise ValidationError(_("A user with this username or e-mail already exists."))
user.set_password(event_registration["user"]["password"])
user.save()
else:
user = info.context.user
try:
person, created = Person.objects.get_or_create(
user=user,
defaults={
"email": email,
"first_name": event_registration["person"]["first_name"],
"last_name": event_registration["person"]["last_name"],
},
)
except IntegrityError:
raise ValidationError(_("A person with using the e-mail address %s already exists." % email))
# Store contact information in database
for field_name in ["date_of_birth", "sex", "address", "mobile_number"]:
if event_registration["person"] is not None and event_registration["person"][field_name] != "":
if field_name == "address":
for addr_field in ["street", "housenumber", "postal_code", "place"]:
setattr(person, addr_field, event_registration["person"]["address"][addr_field])
else:
setattr(person, field_name, event_registration["person"][field_name])
person.save()
if event_registration["person"] is not None:
for guardian_data in event_registration["person"]["guardians"]:
if hasattr(guardian_data, "id"):
guardian = Person.objects.get(pk=guardian_data["id"])
guardian.first_name=guardian_data["first_name"]
guardian.last_name=guardian_data["last_name"]
guardian.email=guardian_data["email"]
guardian.mobile_number=guardian_data["mobile_number"]
guardian.save()
else:
try:
guardian, created = Person.objects.get_or_create(
defaults={
"mobile_number": guardian_data["mobile_number"],
},
first_name=guardian_data["first_name"],
last_name=guardian_data["last_name"],
email=guardian_data["email"],
)
except IntegrityError:
raise ValidationError(_("A person with using the e-mail address %s already exists." % guardian_data["email"]))
person.guardians.add(guardian)
person.save()
if event_registration["email"] is not None:
_mail_address.person = person
_mail_address.save()
school_details = {}
for field_name in ["school", "school_class", "school_place"]:
if event_registration[field_name] is not None:
school_details[field_name] = event_registration[field_name]
registration = EventRegistration.objects.create(
managed_by_app_label="",
event=event,
person=person,
medical_information=event_registration["medical_information"],
donation=0,
**school_details,
)
for field in event.additional_fields.all():
registration.extended_data[
slugify(field.title).replace("-", "_")
] = event_registration["additional_fields"][str(field.id)]
for field in event_registration["terms"]:
pk = field
term = Terms.objects.get(id=pk)
registration.accepted_terms.add(term)
registration.cost = event.cost
if event.max_cost is None or event.max_cost > 0:
amount = event_registration["payment"]["amount"]
if amount < event.cost:
voucher_amount = event.cost - amount
discount = voucher_amount / event.cost * 100
voucher = Voucher.objects.create(
person=person,
event=event,
used=True,
discount=discount,
)
registration.voucher = voucher
elif amount > event.cost:
registration.donation = amount - event.cost
# TODO Implement existing voucher handling
invoice = registration.get_invoice()
invoice.variant = event_registration["payment"]["payment_method"]
invoice.save()
registration.save()
context = {}
context["registration"] = registration
# send_templated_mail(
# template_name="event_registered",
# from_email=get_site_preferences()["mail__address"],
# recipient_list=[get_site_preferences()["paweljong__event_notification_recipient"]],
# headers={
# "reply_to": [
# person.email,
# person.guardians.first().email,
# ],
# "X-Zammad-Customer-Email": person.email,
# },
# context=context,
# )
_act = Activity(
title=_("You registered for an event"),
description=_("You registered for the event %s" % event.display_name),
app="Paweljong",
user=person,
)
return SendEventRegistrationMutation(ok=True)