From fd1a9915dd65789cccf27041a1f01cd4077273fc Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 6 Sep 2022 01:21:37 +0200 Subject: [PATCH] New layout pages. --- .../templates/catalogue/2022/book_box.html | 6 +- .../catalogue/2022/theme_detail.html | 98 ++++++++++++ src/catalogue/tests/test_tags.py | 2 +- src/catalogue/views.py | 3 + src/club/admin.py | 15 +- src/club/forms.py | 81 ++++++++++ src/club/migrations/0040_amount.py | 38 +++++ src/club/migrations/0041_move_amounts.py | 40 +++++ .../migrations/0042_auto_20220826_1458.py | 21 +++ src/club/models.py | 30 +++- src/club/payment_methods.py | 50 +++++++ src/club/static/club/payu/banki.png | Bin 0 -> 845103 bytes .../templates/club/2022/donation_step1.html | 139 ++++++++++++++++++ .../templates/club/2022/donation_step2.html | 109 ++++++++++++++ .../templates/club/2022/donation_step3.html | 103 +++++++++++++ .../templates/club/2022/donation_step4.html | 15 ++ .../club/2022/donation_step_base.html | 130 ++++++++++++++++ .../templates/club/payment/paypal_invite.html | 7 + .../templates/club/payment/payu_invite.html | 5 + src/club/templates/club/payment_form.html | 8 +- src/club/templates/payu/rec_widget.html | 26 ++++ src/club/templatetags/club.py | 5 + src/club/urls.py | 2 + src/club/views.py | 85 +++++++++-- src/paypal/urls.py | 1 + src/paypal/views.py | 10 +- src/wolnelektury/static/2021/scripts/main.js | 20 +-- .../static/2022/images/checkout-bg.png | Bin 0 -> 19957 bytes .../static/2022/images/checkout-img-4.jpg | Bin 0 -> 165947 bytes src/wolnelektury/static/2022/more.scss | 79 ++++++++++ .../static/2022/styles/layout/_module.scss | 2 + .../2022/styles/layout/_pagination.scss | 52 +++++++ .../static/2022/styles/layout/_theme.scss | 67 +++++++++ src/wolnelektury/templates/2022/paginate.html | 27 ++++ 34 files changed, 1229 insertions(+), 47 deletions(-) create mode 100644 src/catalogue/templates/catalogue/2022/theme_detail.html create mode 100644 src/club/migrations/0040_amount.py create mode 100644 src/club/migrations/0041_move_amounts.py create mode 100644 src/club/migrations/0042_auto_20220826_1458.py create mode 100644 src/club/static/club/payu/banki.png create mode 100644 src/club/templates/club/2022/donation_step1.html create mode 100644 src/club/templates/club/2022/donation_step2.html create mode 100644 src/club/templates/club/2022/donation_step3.html create mode 100644 src/club/templates/club/2022/donation_step4.html create mode 100644 src/club/templates/club/2022/donation_step_base.html create mode 100644 src/club/templates/club/payment/paypal_invite.html create mode 100644 src/club/templates/club/payment/payu_invite.html create mode 100644 src/club/templates/payu/rec_widget.html create mode 100644 src/wolnelektury/static/2022/images/checkout-bg.png create mode 100644 src/wolnelektury/static/2022/images/checkout-img-4.jpg create mode 100644 src/wolnelektury/static/2022/styles/layout/_pagination.scss create mode 100644 src/wolnelektury/static/2022/styles/layout/_theme.scss create mode 100644 src/wolnelektury/templates/2022/paginate.html diff --git a/src/catalogue/templates/catalogue/2022/book_box.html b/src/catalogue/templates/catalogue/2022/book_box.html index 83b415744..55f851de9 100644 --- a/src/catalogue/templates/catalogue/2022/book_box.html +++ b/src/catalogue/templates/catalogue/2022/book_box.html @@ -1,12 +1,12 @@ {% load sorl_thumbnail %}
-
+
{% if book.is_picture %} {% if book.image_file %} - {% thumbnail book.image_file "170x170" as im %} - + {% thumbnail book.image_file "170x240" crop="center" as im %} + {% endthumbnail %} {% endif %} {% else %} diff --git a/src/catalogue/templates/catalogue/2022/theme_detail.html b/src/catalogue/templates/catalogue/2022/theme_detail.html new file mode 100644 index 000000000..622b6b521 --- /dev/null +++ b/src/catalogue/templates/catalogue/2022/theme_detail.html @@ -0,0 +1,98 @@ +{% extends '2022/base_real.html' %} +{% load pagination_tags %} + +{% block content %} +
+ +
+ +
+ +
+
+

Motyw: {{ tags.0.name }}

+
+
+ + + + {% autopaginate object_list 10 %} + +
+
+
+
+ + {% for fragment in object_list %} + + {% endfor %} + {% paginate using '2022/paginate.html' %} +
+
+
+
+

Motyw: {{ tags.0.name }}

+ {{ tags.0.description|safe }} + +
+
+
+
+
+ +{% endblock %} diff --git a/src/catalogue/tests/test_tags.py b/src/catalogue/tests/test_tags.py index 92845e228..a7066186c 100644 --- a/src/catalogue/tests/test_tags.py +++ b/src/catalogue/tests/test_tags.py @@ -291,4 +291,4 @@ class BookTagsTests(WLTestCase): self.assertEqual([t.slug for t in book.tags.filter(category='kind')], ['kind']) self.assertEqual([(tag.name, tag.count) for tag in related_themes], - [('ChildTheme', 1), ('ParentTheme', 1), ('Theme', 2)]) + [('Theme', 2), ('ChildTheme', 1), ('ParentTheme', 1)]) diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 6edbbd6a4..c63aa7a9e 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -144,9 +144,12 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None, result.update(extra) is_author = len(tags) == 1 and tags[0].category == 'author' + is_theme = len(tags) == 1 and tags[0].category == 'theme' new_layout = request.EXPERIMENTS['layout'] if is_author and new_layout.value: template = 'catalogue/2022/author_detail.html' + elif is_theme and new_layout.value: + template = 'catalogue/2022/theme_detail.html' else: template = 'catalogue/tagged_object_list.html' diff --git a/src/club/admin.py b/src/club/admin.py index d966ad64d..ce74ec61b 100644 --- a/src/club/admin.py +++ b/src/club/admin.py @@ -14,7 +14,20 @@ from wolnelektury.utils import YesNoFilter from . import models -admin.site.register(models.Club) +class SingleAmountInline(admin.TabularInline): + model = models.SingleAmount + + +class MonthlyAmountInline(admin.TabularInline): + model = models.MonthlyAmount + + +@admin.register(models.Club) +class ClubAdmin(admin.ModelAdmin): + inlines = [ + SingleAmountInline, + MonthlyAmountInline + ] class PayUOrderInline(admin.TabularInline): diff --git a/src/club/forms.py b/src/club/forms.py index 3a844dab4..f91985539 100644 --- a/src/club/forms.py +++ b/src/club/forms.py @@ -115,3 +115,84 @@ Twoje dane osobowe nie będą profilowane, ani przesyłane do państw trzecich i class PayUCardTokenForm(CardTokenForm): def get_queryset(self, view): return view.get_schedule().payucardtoken_set + + + +class DonationStep1Form(forms.ModelForm): + switch = forms.CharField() + single_amount = forms.IntegerField(required=False) + monthly_amount = forms.IntegerField(required=False) + single_amount_selected = forms.IntegerField(required=False) + monthly_amount_selected = forms.IntegerField(required=False) + custom_amount = forms.IntegerField(required=False) + + amount = forms.IntegerField(required=False) # hidden + + class Meta: + model = models.Schedule + fields = [ + 'amount', + 'monthly' + ] + + + def clean(self): + state = {} + state['monthly'] = self.cleaned_data['switch'] == 'monthly' + which = 'monthly' if state['monthly'] else 'single' + state['amount'] = \ + self.cleaned_data[f'{which}_amount'] or \ + self.cleaned_data['custom_amount'] or \ + self.cleaned_data[f'{monthly}_amount_selected'] + + return state + + + +class DonationStep2Form(forms.ModelForm, NewsletterForm): + class Meta: + model = models.Schedule + fields = [ + 'first_name', 'last_name', + 'email', 'phone', + 'postal', + 'postal_code', 'postal_town', 'postal_country', + ] + widgets = { + 'amount': forms.HiddenInput, + 'monthly': forms.HiddenInput, + } + + def __init__(self, referer=None, **kwargs): + self.referer = referer + super().__init__(**kwargs) + + self.fields['first_name'].required = True + self.fields['last_name'].required = True + self.fields['phone'].required = True + + self.consent = [] + for c in models.Consent.objects.filter(active=True).order_by('order'): + key = f'consent{c.id}' + self.fields[key] = forms.BooleanField( + label=c.text, + required=c.required + ) + self.consent.append(( + c, key, (lambda k: lambda: self[k])(key) + )) + + + + def save(self, *args, **kwargs): + NewsletterForm.save(self, *args, **kwargs) + self.instance.source = self.referer or '' + instance = super().save(*args, **kwargs) + + consents = [] + for consent, key, consent_field in self.consent: + if self.cleaned_data[key]: + instance.consent.add(consent) + + return instance + diff --git a/src/club/migrations/0040_amount.py b/src/club/migrations/0040_amount.py new file mode 100644 index 000000000..1a1215508 --- /dev/null +++ b/src/club/migrations/0040_amount.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.27 on 2022-08-26 12:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('club', '0039_auto_20220421_0109'), + ] + + operations = [ + migrations.CreateModel( + name='SingleAmount', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.IntegerField()), + ('description', models.TextField(blank=True)), + ('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='club.Club')), + ], + options={ + 'ordering': ['amount'], + }, + ), + migrations.CreateModel( + name='MonthlyAmount', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.IntegerField()), + ('description', models.TextField(blank=True)), + ('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='club.Club')), + ], + options={ + 'ordering': ['amount'], + }, + ), + ] diff --git a/src/club/migrations/0041_move_amounts.py b/src/club/migrations/0041_move_amounts.py new file mode 100644 index 000000000..d920fd0d3 --- /dev/null +++ b/src/club/migrations/0041_move_amounts.py @@ -0,0 +1,40 @@ +# Generated by Django 2.2.27 on 2022-08-26 12:39 + +from django.db import migrations + + +def move_amounts(apps, schema_editor): + Club = apps.get_model('club', 'Club') + for club in Club.objects.all(): + for amount in [int(x) for x in club.single_amounts.split(',')]: + club.singleamount_set.create(amount=amount) + for amount in [int(x) for x in club.monthly_amounts.split(',')]: + club.monthlyamount_set.create(amount=amount) + + +def move_amounts_back(apps, schema_editor): + Club = apps.get_model('club', 'Club') + for club in Club.objects.all(): + club.single_amounts = ','.join( + str(x) for x in + club.singleamount_set.order_by('amount') + ) + club.monthly_amounts = ','.join( + str(x) for x in + club.monthlyamount_set.order_by('amount') + ) + club.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('club', '0040_amount'), + ] + + operations = [ + migrations.RunPython( + move_amounts, + move_amounts_back + ) + ] diff --git a/src/club/migrations/0042_auto_20220826_1458.py b/src/club/migrations/0042_auto_20220826_1458.py new file mode 100644 index 000000000..187e5ebfc --- /dev/null +++ b/src/club/migrations/0042_auto_20220826_1458.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.27 on 2022-08-26 12:58 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('club', '0041_move_amounts'), + ] + + operations = [ + migrations.RemoveField( + model_name='club', + name='monthly_amounts', + ), + migrations.RemoveField( + model_name='club', + name='single_amounts', + ), + ] diff --git a/src/club/models.py b/src/club/models.py index 4f3a8f632..acf131b12 100644 --- a/src/club/models.py +++ b/src/club/models.py @@ -26,9 +26,7 @@ from . import utils class Club(models.Model): min_amount = models.IntegerField(_('minimum amount')) min_for_year = models.IntegerField(_('minimum amount for year')) - single_amounts = models.CharField(_('proposed amounts for single payment'), max_length=255) default_single_amount = models.IntegerField(_('default single amount')) - monthly_amounts = models.CharField(_('proposed amounts for monthly payments'), max_length=255) default_monthly_amount = models.IntegerField(_('default monthly amount')) class Meta: @@ -37,12 +35,23 @@ class Club(models.Model): def __str__(self): return 'Klub' - - def proposed_single_amounts(self): - return [int(x) for x in self.single_amounts.split(',')] - def proposed_monthly_amounts(self): - return [int(x) for x in self.monthly_amounts.split(',')] + +class SingleAmount(models.Model): + club = models.ForeignKey(Club, models.CASCADE) + amount = models.IntegerField() + description = models.TextField(blank=True) + + class Meta: + ordering = ['amount'] + +class MonthlyAmount(models.Model): + club = models.ForeignKey(Club, models.CASCADE) + amount = models.IntegerField() + description = models.TextField(blank=True) + + class Meta: + ordering = ['amount'] class Consent(models.Model): @@ -116,6 +125,13 @@ class Schedule(models.Model): def get_payment_method(self): return [m for m in methods if m.slug == self.method][0] + def get_payment_methods(self): + for method in methods: + if (self.monthly or self.yearly) and method.is_recurring: + yield method + elif not (self.monthly or self.yearly) and method.is_onetime: + yield method + def is_expired(self): return self.expires_at is not None and self.expires_at <= now() diff --git a/src/club/payment_methods.py b/src/club/payment_methods.py index e74ae83ca..9fddff3ff 100644 --- a/src/club/payment_methods.py +++ b/src/club/payment_methods.py @@ -1,10 +1,14 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +from hashlib import sha256 from django.conf import settings from django.urls import reverse from django.utils.timezone import now +from django.utils.translation import get_language from paypal.rest import agreement_approval_url +from django.template.loader import render_to_string +from .payu import POSS class PaymentMethod(object): @@ -28,6 +32,14 @@ class PayU(PaymentMethod): def __init__(self, pos_id): self.pos_id = pos_id + def invite_widget(self, schedule): + return render_to_string( + 'club/payment/payu_invite.html', + { + 'schedule': schedule, + } + ) + def initiate(self, request, schedule): # Create Order at once. from .models import PayUOrder @@ -54,6 +66,36 @@ class PayURe(PaymentMethod): def initiate(self, request, schedule): return reverse('club_payu_rec_payment', args=[schedule.key]) + def invite_widget(self, schedule): + from . import forms + pos = POSS[self.pos_id] + widget_args = { + 'merchant-pos-id': pos.pos_id, + 'shop-name': "SHOW NAME", + 'total-amount': str(int(schedule.amount * 100)), + 'currency-code': pos.currency_code, + 'customer-language': get_language(), # filter to pos.languages + 'customer-email': schedule.email, + 'store-card': 'true', + 'recurring-payment': 'true', + } + widget_sig = sha256( + ( + "".join(v for (k, v) in sorted(widget_args.items())) + + pos.secondary_key + ).encode('utf-8') + ).hexdigest() + + return render_to_string( + 'payu/rec_widget.html', + { + 'form': forms.PayUCardTokenForm(), + 'pos': POSS[self.pos_id], + 'widget_args': widget_args, + 'widget_sig': widget_sig, + } + ) + def pay(self, request, schedule): # Create order, put it and see what happens next. from .models import PayUOrder @@ -104,6 +146,14 @@ class PayPal(PaymentMethod): is_recurring = True is_onetime = False + def invite_widget(self, schedule): + return render_to_string( + 'club/payment/paypal_invite.html', + { + 'schedule': schedule, + } + ) + def initiate(self, request, schedule): app = request.GET.get('app') return agreement_approval_url(schedule.amount, schedule.key, app=app) diff --git a/src/club/static/club/payu/banki.png b/src/club/static/club/payu/banki.png new file mode 100644 index 0000000000000000000000000000000000000000..528ce8b12f04c6fef4e42e7ab041de12d06e615b GIT binary patch literal 845103 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