Newer
Older
from django.db import transaction, IntegrityError
from django.contrib.auth.models import User
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, MailDomain
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=False) # FIXME: Fix frontend to allow 0, then make field required again
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()
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)
email = None
if event_registration["email"] is not None:
try:
domain = MailDomain.objects.get(pk=event_registration["email"]["domain"])
except IntegrityError:
raise ValidationError(_("Mail domain does not exist."))
try:
_mail_address = MailAddress.objects.create(
local_part=event_registration["email"]["local_part"],
)
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"]
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:
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 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] 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"]:
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 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"],
**school_details,
)
for field in event.additional_fields.all():
if hasattr(event_registration["additional_fields"], str(field.id)):
registration.extended_data[
slugify(field.title).replace("-", "_")
] = event_registration["additional_fields"][str(field.id)]
for field in event_registration["terms"]:
term = Terms.objects.get(id=pk)
registration.accepted_terms.add(term)
registration.cost = event.cost
if amount is None:
raise ValidationError(_("The field 'Amount paid by you' is required."))
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,
)
elif amount > event.cost:
registration.donation = amount - event.cost
# TODO Implement existing voucher handling
invoice = registration.get_invoice()
if amount == 0:
invoice.variant = "pledge"
else:
invoice.variant = event_registration["payment"]["payment_method"]
if invoice.variant == "" or invoice.variant is None:
raise ValidationError(_("The field 'Payment method' is required."))
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
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)