Verified Commit f837d414 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Use Payment object to register event payments

parent 23b79eb4
......@@ -3,6 +3,7 @@
from django.contrib import admin
from django.core.exceptions import DisallowedRedirect, PermissionDenied
from django.db.models import Max, Min
from django.forms import Field
from django.http import HttpResponseRedirect
from django.template.defaultfilters import date as _date
from django.urls import reverse, path
......@@ -15,6 +16,7 @@ from django.utils.translation import ugettext_lazy as _
from activemembers.models import MemberGroup
from events import services
from members.models import Member
from payments.widgets import PaymentWidget
from pizzas.models import PizzaEvent
from utils.snippets import datetime_to_lectureyear
from utils.translation import TranslatedModelAdmin
......@@ -301,6 +303,10 @@ class RegistrationAdmin(DoNextModelAdmin):
field.widget.can_add_related = False
field.widget.can_change_related = False
field.widget.can_delete_related = False
elif db_field.name == 'payment':
return Field(widget=PaymentWidget,
initial=field.initial,
required=False)
return field
def formfield_for_foreignkey(self, db_field, request, **kwargs):
......
......@@ -7,6 +7,7 @@ from html import unescape
from rest_framework import serializers
from rest_framework.fields import empty
from payments.models import Payment
from thaliawebsite.api.services import create_image_thumbnail_dict
from events import services
from events.exceptions import RegistrationError
......@@ -255,9 +256,18 @@ class RegistrationAdminListSerializer(RegistrationListSerializer):
return instance.name
class PaymentTypeField(serializers.ChoiceField):
def get_attribute(self, instance):
if not instance.payment:
return Payment.NONE
return super().get_attribute(instance)
class RegistrationSerializer(serializers.ModelSerializer):
"""Registration serializer"""
information_fields = None
requesting_user = None
class Meta:
model = Registration
......@@ -270,6 +280,8 @@ class RegistrationSerializer(serializers.ModelSerializer):
photo = serializers.SerializerMethodField('_photo')
avatar = serializers.SerializerMethodField('_avatar')
member = serializers.SerializerMethodField('_member')
payment = PaymentTypeField(source='payment.type',
choices=Payment.PAYMENT_TYPE)
registered_on = serializers.DateTimeField(source='date', read_only=True)
is_cancelled = serializers.SerializerMethodField('_is_cancelled')
is_late_cancellation = serializers.SerializerMethodField(
......@@ -317,8 +329,14 @@ class RegistrationSerializer(serializers.ModelSerializer):
self.context['request'], file, placeholder=placeholder,
size_large='800x800')
def _payment(self, instance):
if instance.payment:
return instance.payment.type
return Registration.PAYMENT_NONE
def __init__(self, instance=None, data=empty, **kwargs):
super().__init__(instance, data, **kwargs)
self.requesting_user = kwargs['context']['request'].member
try:
if instance:
self.information_fields = services.registration_fields(
......
# Generated by Django 2.1.3 on 2018-11-26 19:30
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('payments', '0002_auto_20181127_1819'),
('events', '0032_event_documents'),
]
operations = [
migrations.RenameField(
model_name='registration',
old_name='payment',
new_name='payment_str',
),
migrations.AddField(
model_name='registration',
name='payment',
field=models.OneToOneField(null=True, blank=True,
on_delete=django.db.models.deletion.PROTECT,
related_name='events_registration',
to='payments.Payment'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-07-21 19:18
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0033_registration_payment_obj'),
]
def forwards_func(apps, schema_editor):
Registration = apps.get_model('events', 'registration')
Payment = apps.get_model('payments', 'payment')
db_alias = schema_editor.connection.alias
for reg in Registration.objects.using(db_alias).all():
if reg.event.price > 0 and reg.payment_str != 'no_payment':
reg.payment = Payment.objects.create(
created_at=reg.date,
type=reg.payment_str,
amount=reg.event.price,
paid_by=reg.member,
processing_date=reg.event.start,
notes=f'Event registration {reg.event}. '
f'Registration: {reg}'
)
reg.save()
def reverse_func(apps, schema_editor):
Registration = apps.get_model('events', 'registration')
db_alias = schema_editor.connection.alias
for reg in Registration.objects.using(db_alias).all():
if reg.payment:
reg.payment.delete()
operations = [
migrations.RunPython(forwards_func, reverse_func),
]
# Generated by Django 2.1.3 on 2018-11-30 14:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0034_registration_payment_obj'),
]
operations = [
migrations.RemoveField(
model_name='registration',
name='payment_str',
),
]
......@@ -12,6 +12,7 @@ from django.utils.text import format_lazy
from tinymce.models import HTMLField
from members.models import Member
from payments.models import Payment
from pushnotifications.models import ScheduledMessage, Category
from utils.translation import ModelTranslateMeta, MultilingualField
......@@ -424,14 +425,9 @@ def registration_member_choices_limit():
class Registration(models.Model):
"""Describes a registration for an Event"""
PAYMENT_CARD = 'card_payment'
PAYMENT_CASH = 'cash_payment'
PAYMENT_NONE = 'no_payment'
PAYMENT_TYPES = (
(PAYMENT_NONE, _('No payment')),
(PAYMENT_CASH, _('Paid with cash')),
(PAYMENT_CARD, _('Paid with card')))
PAYMENT_NONE = Payment.NONE
PAYMENT_CARD = Payment.CARD
PAYMENT_CASH = Payment.CASH
event = models.ForeignKey(Event, models.CASCADE)
......@@ -461,11 +457,12 @@ class Registration(models.Model):
default=False,
)
payment = models.CharField(
choices=PAYMENT_TYPES,
default='no_payment',
verbose_name=_('payment'),
max_length=20,
payment = models.OneToOneField(
'payments.Payment',
related_name='events_registration',
on_delete=models.PROTECT,
blank=True,
null=True,
)
@property
......@@ -514,8 +511,7 @@ class Registration(models.Model):
).count() < self.event.max_participants))
def is_paid(self):
return self.payment in [Registration.PAYMENT_CARD,
Registration.PAYMENT_CASH]
return self.payment and self.payment.processed
def would_cancel_after_deadline(self):
now = timezone.now()
......
......@@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _, get_language
from events import emails
from events.exceptions import RegistrationError
from events.models import Registration, RegistrationInformationField
from payments.models import Payment
def is_user_registered(member, event):
......@@ -241,7 +242,26 @@ def update_registration_by_organiser(registration, member, data):
_("You are not allowed to update this registration."))
if 'payment' in data:
registration.payment = data['payment']
if (data['payment']['type'] == Payment.NONE
and registration.payment is not None):
p = registration.payment
registration.payment = None
registration.save()
p.delete()
elif (data['payment']['type'] != Payment.NONE
and registration.payment is not None):
registration.payment.type = data['payment']['type']
registration.payment.save()
elif (data['payment']['type'] == Payment.NONE
and registration.payment is None):
registration.payment = Payment.objects.create(
amount=registration.event.price,
paid_by=registration.member,
notes=(f'Event registration {registration.event.title_en}. '
f'Registration date: {registration.date}'),
processed_by=member,
type=data['payment']['type']
)
if 'present' in data:
registration.present = data['present']
......
......@@ -50,10 +50,12 @@
<td>{{ field.value }}</td>
{% endif %}
{% endfor %}
<td><input type="checkbox" {{ registration.present|yesno:'checked="checked",' }} class="present-check" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if registration.payment == registration.PAYMENT_NONE %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_NONE }}" class="payment-radio" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if registration.payment == registration.PAYMENT_CASH %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_CASH }}" class="payment-radio" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if registration.payment == registration.PAYMENT_CARD %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_CARD }}" class="payment-radio" /></td>
<td><input type="checkbox" {{ registration.present|yesno:'checked="checked",' }} data-id="{{ registration.id }}" class="present-check" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if not registration.payment %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_NONE }}" data-id="{{ registration.id }}" class="payment-radio" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if registration.payment and registration.payment.type == registration.PAYMENT_CASH %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_CASH }}" data-id="{{ registration.id }}" class="payment-radio" /></td>
<td><input type="radio" name="payment-{{ registration.id }}" {% if registration.payment and registration.payment.type == registration.PAYMENT_CARD %}checked="checked"{% endif %} data-value="{{ registration.PAYMENT_CARD }}" data-id="{{ registration.id }}" class="payment-radio" /></td>
{% if registration.date_cancelled is not None %}
<td>{{ registration.is_late_cancellation|yesno }}</td>
{% endif %}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment