Skip to content
Snippets Groups Projects
Commit 5930868f authored by jan.bednarik's avatar jan.bednarik
Browse files

donate: Targeted donations

parent d0ad67a1
No related branches found
No related tags found
No related merge requests found
......@@ -8,11 +8,13 @@ class DonateForm(forms.Form):
CUSTOM_AMOUNT = -1
DEFAULT_CUSTOM_AMOUNT = 1000
ALLOWED_PERIODICITY = [730, 99999]
PORTAL_ID_IN_SELECT = -1
amount = forms.IntegerField()
custom_amount = forms.IntegerField(required=False)
periodicity = forms.IntegerField()
portal_project_id = forms.IntegerField()
select_portal_project_id = forms.IntegerField(required=False)
def clean_periodicity(self):
value = self.cleaned_data["periodicity"]
......@@ -32,6 +34,8 @@ class DonateForm(forms.Form):
amount = self.get_amount()
periodicity = self.cleaned_data["periodicity"]
portal_project_id = self.cleaned_data["portal_project_id"]
if portal_project_id == self.PORTAL_ID_IN_SELECT:
portal_project_id = self.cleaned_data["select_portal_project_id"]
query = urllib.parse.urlencode(
{
"amount": amount,
......
# Generated by Django 3.1.1 on 2020-09-14 23:14
import django.db.models.deletion
import modelcluster.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("donate", "0011_donateprojectpage_form_preselected"),
]
operations = [
migrations.RemoveField(
model_name="donatetargeteddonationspage", name="targeted_donations",
),
migrations.CreateModel(
name="TargetedDonation",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"sort_order",
models.IntegerField(blank=True, editable=False, null=True),
),
(
"is_main",
models.BooleanField(
default=False,
help_text="zobrazené samostatně nahoře",
verbose_name="hlavní dar",
),
),
("title", models.CharField(max_length=255, verbose_name="název")),
(
"description",
models.CharField(
blank=True,
help_text="zobrazí se jen u hlavních darů",
max_length=255,
null=True,
verbose_name="popis",
),
),
(
"portal_project_id",
models.IntegerField(verbose_name="ID projektu v darovacím portálu"),
),
(
"page",
modelcluster.fields.ParentalKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="targeted_donations",
to="donate.donatetargeteddonationspage",
),
),
],
options={"ordering": ["sort_order"], "abstract": False,},
),
]
......@@ -4,16 +4,18 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import models
from django.shortcuts import redirect
from django.utils.translation import gettext_lazy
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import (
FieldPanel,
HelpPanel,
InlinePanel,
MultiFieldPanel,
PublishingPanel,
StreamFieldPanel,
)
from wagtail.core import blocks
from wagtail.core.fields import RichTextField, StreamField
from wagtail.core.models import Page
from wagtail.core.models import Orderable, Page
from wagtail.images.blocks import ImageChooserBlock
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtailmetadata.models import MetadataPageMixin
......@@ -574,17 +576,31 @@ class DonateInfoPage(DonateFormMixin, Page, SubpageMixin, MetadataPageMixin):
return self.get_parent().specific.portal_project_id
class TargetedDonationBlock(blocks.StructBlock):
title = blocks.CharBlock(label="název")
description = blocks.CharBlock(label="popis", required=False)
portal_project_id = blocks.IntegerBlock(
label="ID projektu v darovacím portálu",
required=False,
help_text="Pokud není zadáno ID projektu, tak se adresný dar nezobrazí.",
class TargetedDonation(Orderable):
page = ParentalKey(
"donate.DonateTargetedDonationsPage",
on_delete=models.CASCADE,
related_name="targeted_donations",
)
is_main = models.BooleanField(
"hlavní dar", default=False, help_text="zobrazené samostatně nahoře"
)
title = models.CharField("název", max_length=255)
description = models.CharField(
"popis",
null=True,
blank=True,
max_length=255,
help_text="zobrazí se jen u hlavních darů",
)
portal_project_id = models.IntegerField("ID projektu v darovacím portálu")
class Meta:
label = "adresný dar"
panels = [
FieldPanel("portal_project_id"),
FieldPanel("title"),
FieldPanel("description"),
FieldPanel("is_main"),
]
class DonateTargetedDonationsPage(
......@@ -592,17 +608,13 @@ class DonateTargetedDonationsPage(
):
### FIELDS
targeted_donations = StreamField(
[("item", TargetedDonationBlock())], verbose_name="adresné dary", blank=True
)
# page does not have specific portal_project_id
portal_project_id = None
### PANELS
content_panels = Page.content_panels + [
StreamFieldPanel("targeted_donations"),
MultiFieldPanel([InlinePanel("targeted_donations")], "adresné dary"),
]
promote_panels = [
......@@ -630,6 +642,33 @@ class DonateTargetedDonationsPage(
class Meta:
verbose_name = "Adresné dary"
@property
def show_donate_form(self):
return bool(self.targeted_donations)
def get_context(self, request):
context = super().get_context(request)
try:
selected_project_id = int(request.GET.get("p", 0))
selected_target = self.targeted_donations.get(
portal_project_id=selected_project_id
)
except (ValueError, TargetedDonation.DoesNotExist):
selected_target = None
if selected_target:
context["main_targets"] = [selected_target]
context["other_targets"] = []
context["is_preselected"] = True
else:
context["main_targets"] = self.targeted_donations.filter(is_main=True)
context["other_targets"] = self.targeted_donations.filter(is_main=False)
context["is_preselected"] = False
if context["main_targets"]:
context["initial_project_id"] = context["main_targets"][0].portal_project_id
elif context["other_targets"]:
context["initial_project_id"] = context["other_targets"][
0
].portal_project_id
else:
context["initial_project_id"] = 0
return context
......@@ -752,6 +752,15 @@ footer h1, footer h2, footer h3, footer h4, footer h5, footer h6 {
height: 2rem;
}
.custom-control-label-for-select {
line-height: 1;
padding-top: 0.4rem;
}
.custom-control-select {
padding: 0.3rem;
}
.custom-control-input {
width: 2rem;
height: 2.5rem;
......
......@@ -50,26 +50,51 @@
/* DONATE FORM */
// On amount radio change
$("input[name='amount']").change(function() {
// On amount radio change
$("input[name='amount']").change(function() {
// If custom amount is selected
if($(this).attr('id') == 'amount4') {
// If custom amount is selected
if($(this).attr('id') == 'amount4') {
// Show custom amount input and set it required
$("#js-custom-amount-input").show(50);
$('#customamount').attr('required', true);
// Show custom amount input and set it required
$("#js-custom-amount-input").show(50);
$('#customamount').attr('required', true);
} else {
} else {
// Hide custom amount and remove required field
$("#js-custom-amount-input").hide(50);
$('#customamount').attr('required', false);
// Hide custom amount and remove required field
$("#js-custom-amount-input").hide(50);
$('#customamount').attr('required', false);
}
});
// Trigger correct state onload
$("input[name='amount']:checked").change();
// Update sharing link on form change for target donations
function updateLink(projectId) {
var url = new URL(location.href);
url.searchParams.set("p", projectId);
console.log(url.href);
$("#target_sharing_link").attr("href", url.href);
}
});
// Trigger correct state onload
$("input[name='amount']:checked").change();
$("input:radio.target-radio").change(function () {
if ($(this).is(":checked")) {
if ($(this).val() == -1) {
updateLink($("#other_target_select").val());
} else {
updateLink($(this).val());
}
}
});
$("#other_target_select").change(function () {
if ($("#other_target").is(":checked")) {
updateLink($("#other_target_select").val());
}
});
})(jQuery);
......@@ -15,20 +15,35 @@
<section class="section--primary section--form">
<div class="container">
{% if page.show_donate_form %}
<form id="js-donate-form" method="post">
{% if main_targets or other_targets %}
<form id="js-donate-form" class="sharing-link" method="post">
{% csrf_token %}
<div class="form-group row mb-4 align-items-center">
<div class="col-12">
{% for target in page.targeted_donations %}
{% if target.value.portal_project_id %}
{% for target in main_targets %}
{% if target.portal_project_id %}
<div class="custom-control custom-radio my-3">
<input type="radio" id="target{{ forloop.counter }}" name="portal_project_id" value="{{ target.value.portal_project_id }}" class="custom-control-input"{% if forloop.first %} checked required{% endif %}>
<label class="custom-control-label col-form-label-lg" for="target{{ forloop.counter }}">{{ target.value.title }}<br> <span class="small">{{ target.value.description }}</span></label>
<input type="radio" id="main_target{{ forloop.counter }}" name="portal_project_id" value="{{ target.portal_project_id }}" class="custom-control-input target-radio"{% if forloop.first %} checked required{% endif %}>
<label class="custom-control-label col-form-label-lg" for="main_target{{ forloop.counter }}">{{ target.title }}<br> <span class="small">{{ target.description|default:"" }}</span></label>
</div>
{% endif %}
{% endfor %}
{% if other_targets %}
<div class="custom-control custom-radio my-3">
<input type="radio" id="other_target" name="portal_project_id" value="-1" class="custom-control-input target-radio"{% if not main_targets %} checked required{% endif %}>
<label class="custom-control-label col-form-label-lg custom-control-label-for-select" for="other_target">
<select id="other_target_select" name="select_portal_project_id" class="custom-control-select">
{% for target in other_targets %}
<option value="{{ target.portal_project_id }}">{{ target.title }}</option>
{% endfor %}
</select>
</label>
</div>
{% endif %}
</div>
</div>
......@@ -54,7 +69,7 @@
</div>
</div>
<div class="form-group row mb-4 align-items-center" id="js-custom-amount-input" style="display: none;">
<div class="offset-md-3 col-md-9">
<div class="offset-md-3 col-md-3">
<div class="input-group input-group-lg mb-3 custom-amount">
<input type="number" class="form-control" id="customamount" name="custom_amount" aria-describedby="customamount-currency">
<div class="input-group-append">
......@@ -82,6 +97,15 @@
</div>
</div>
</form>
<div class="mt-5">
{% if is_preselected %}
<a href="{% pageurl page %}">ukaž všechny adresné dary pro kraj</a>
{% else %}
<a id="target_sharing_link" href="{% pageurl page %}?p={{ initial_project_id }}">odkaz pro sdílení</a>
{% endif %}
</div>
{% else %}
<div class="row mb-4">
<p>Krajské sdružení momentálně nepřijímá adresné dary. Místo toho <a href="{% pageurl page.get_parent %}">podpořte celý kraj!</a></p>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment