diff --git a/aleksis/apps/paweljong/frontend/components/event_registration/eventRegistrationMutation.graphql b/aleksis/apps/paweljong/frontend/components/event_registration/eventRegistrationMutation.graphql index 35d25baae72d5cbacf45d97f4fd1360d02ee6685..ef1b8633f09a04d16a8250b14de3949b9240eb8a 100644 --- a/aleksis/apps/paweljong/frontend/components/event_registration/eventRegistrationMutation.graphql +++ b/aleksis/apps/paweljong/frontend/components/event_registration/eventRegistrationMutation.graphql @@ -1,4 +1,4 @@ -mutation sendOrder( +mutation sendEventRegistration( $event: ID! $eventRegistration: EventRegistrationInputType! ) { diff --git a/aleksis/apps/paweljong/schema/__init__.py b/aleksis/apps/paweljong/schema/__init__.py index ec9ca2a21b425cf2ed543f12cf1d04a38f7776c2..75a300fc50d5d91fb1c1af228a761363bc349d63 100644 --- a/aleksis/apps/paweljong/schema/__init__.py +++ b/aleksis/apps/paweljong/schema/__init__.py @@ -4,22 +4,23 @@ import graphene from graphene_django import DjangoObjectType from graphql import GraphQLError -from aleksis.core.schema.base import FilterOrderList -from aleksis.core.util.core_helpers import get_site_preferences from aleksis.apps.tezor.models.base import Client from aleksis.apps.tezor.models.invoice import InvoiceGroup from aleksis.apps.tezor.schema.client import PaymentVariantChoiceType +from aleksis.core.schema.base import FilterOrderList +from aleksis.core.util.core_helpers import get_site_preferences +from ..models import Event from .checkpoint import CheckpointCheckInMutation from .event import EventType from .event_additional_field import ( EventAdditionalFieldBatchCreateMutation, EventAdditionalFieldBatchDeleteMutation, EventAdditionalFieldBatchPatchMutation, - EventAdditionalFieldType + EventAdditionalFieldType, ) +from .event_registration import SendEventRegistrationMutation from .terms import TermsType -from ..models import Event class Query(graphene.ObjectType): @@ -66,3 +67,5 @@ class Mutation(graphene.ObjectType): create_event_additional_fields = EventAdditionalFieldBatchCreateMutation.Field() delete_event_additional_fields = EventAdditionalFieldBatchDeleteMutation.Field() update_event_additional_fields = EventAdditionalFieldBatchPatchMutation.Field() + + send_event_registration = SendEventRegistrationMutation.Field() diff --git a/aleksis/apps/paweljong/schema/event_registration.py b/aleksis/apps/paweljong/schema/event_registration.py index a63bdf92d2ce12e472830f0097df852ddda9a44c..66ece1aa73c8ceacf41a8dd9ab2b6f46766be501 100644 --- a/aleksis/apps/paweljong/schema/event_registration.py +++ b/aleksis/apps/paweljong/schema/event_registration.py @@ -1,9 +1,20 @@ +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 +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 EventRegistration +from ..models import Event, EventRegistration, Terms, Voucher class EventRegistrationType(PermissionsTypeMixin, DjangoObjectType): @@ -11,16 +22,165 @@ class EventRegistrationType(PermissionsTypeMixin, DjangoObjectType): 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): - full_name = graphene.String(required=True) - email = graphene.String(required=True) - notes = graphene.String(required=False) - shipping_option = graphene.ID(required=True) - payment_option = graphene.ID(required=True) - items = graphene.List(OrderItemInputType, required=True) - shipping_full_name = graphene.String(required=False) - second_address_row = graphene.String(required=False) - street = graphene.String(required=False) - housenumber = graphene.String(required=False) - plz = graphene.String(required=False) - place = graphene.String(required=False) + 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): + event = Event.objects.get(pk=event) + + print(event_registration) + + # Create user + if event_registration is not None: + user = User.objects.create( + username=event_registration["user"]["username"], + email=event_registration["user"]["email"], + ) + user.set_password(event_registration["user"]["password"]) + user.save() + else: + user = self.request.user + + person, created = Person.objects.get_or_create( + user=user, + defaults={ + "email": event_registration["person"]["email"], + "first_name": event_registration["person"]["first_name"], + "last_name": event_registration["person"]["last_name"], + }, + ) + + # 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"]: + 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"], + ) + + person.guardians.add(guardian) + person.save() + + if event_registration["email"] is not None: + _mail_address = MailAddress.objects.create( + local_part=event_registration["email"]["local_part"], + domain=event_registration["email"]["domain"], + ) + _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(): + registration.extended_data[ + slugify(field.title).replace("-", "_") + ] = event_registration["additional_fields"][field.title] + + for field in event_registration["terms"]: + if not field.startswith("consent_"): + continue + pk = int(field.split("_")[1]) + term = Terms.objects.get(id=pk) + registration.accepted_terms.add(term) + + registration.cost = event.cost + + if event.max_cost is not None and event.max_cost > 0: + amount = event_registration["payment"].amount + + if amount < event.cost: + voucher_amount = event.cost - amount + discount = voucher_amount / event.cost + 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() + 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, + ) + + if event_registration["retraction_consent"]: + return SendEventRegistrationMutation(ok=True) + + return SendEventRegistrationMutation(ok=False)