From a59da54513a86ff9c25f2d2362b05e0d72ff284d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Farka?= <stepanfarka11@gmail.com>
Date: Tue, 26 Jul 2022 12:43:07 +0200
Subject: [PATCH] [ADD] crowdfunding rewards

---
 donate/blocks.py                              | 47 +++++++++
 donate/forms.py                               | 28 ++++--
 .../0024_donateprojectpage_crowdfunding.py    | 98 +++++++++++++++++++
 donate/models.py                              | 13 +++
 .../blocks/crowdfunding_reward_block.html     | 47 +++++++++
 .../templates/donate/donate_project_page.html | 11 ++-
 6 files changed, 235 insertions(+), 9 deletions(-)
 create mode 100644 donate/blocks.py
 create mode 100644 donate/migrations/0024_donateprojectpage_crowdfunding.py
 create mode 100644 donate/templates/donate/blocks/crowdfunding_reward_block.html

diff --git a/donate/blocks.py b/donate/blocks.py
new file mode 100644
index 00000000..6dcf2c5c
--- /dev/null
+++ b/donate/blocks.py
@@ -0,0 +1,47 @@
+from django.forms.utils import ErrorList
+from wagtail.blocks import CharBlock, DateBlock, IntegerBlock, ListBlock, StructBlock
+from wagtail.blocks.struct_block import StructBlockValidationError
+from wagtail.images.blocks import ImageChooserBlock
+
+
+class CrowdfundingVariantBlock(StructBlock):
+    reward_id = IntegerBlock(label="ID odměny")
+    title = CharBlock(
+        label="Název varianty", max_length=12, help_text="Například velikost: S"
+    )
+
+    class Meta:
+        icon = "radio-empty"
+
+
+class CrowdfundingRewardBlock(StructBlock):
+    title = CharBlock(label="Název odměny")
+    description = CharBlock(label="Popis", max_length=255, required=False)
+    amount = IntegerBlock(label="Částka")
+    image = ImageChooserBlock(label="Obrázek")
+    delivery_date = DateBlock(label="Datum dodání", required=False)
+    reward_id = IntegerBlock(
+        label="ID odměny",
+        help_text="Vyplňte pouze v případě, že odměna nemá varianty",
+        required=False,
+    )
+    crm_product_description = CharBlock(
+        label="Popis produktu pro CRM",
+        help_text='Bude předán systému v parametru "product"',
+        required=False,
+    )
+    variant_list = ListBlock(
+        CrowdfundingVariantBlock(), label="Varianty", required=False
+    )
+
+    class Meta:
+        template = "donate/blocks/crowdfunding_reward_block.html"
+        icon = "pick"
+        label = "Odměna"
+
+    def clean(self, value):
+        errors = {}
+        if not value["reward_id"] and not value["variant_list"]:
+            errors["reward_id"] = ErrorList(["Musíte vyplnit ID odměny"])
+            raise StructBlockValidationError(errors)
+        return super().clean(value)
diff --git a/donate/forms.py b/donate/forms.py
index cd211ccf..a329d75b 100644
--- a/donate/forms.py
+++ b/donate/forms.py
@@ -10,9 +10,11 @@ class DonateForm(forms.Form):
     PORTAL_ID_IN_SELECT = -1
 
     amount = forms.IntegerField(required=False)
+    crowdfunding = forms.IntegerField(required=False)
     custom_amount = forms.IntegerField(required=False)
     periodicity = forms.IntegerField()
     portal_project_id = forms.IntegerField()
+    product = forms.CharField(required=False)
     select_portal_project_id = forms.IntegerField(required=False)
 
     def clean_periodicity(self):
@@ -42,16 +44,26 @@ class DonateForm(forms.Form):
 
     def get_redirect_url(self):
         amount = self.get_amount()
+        crowdfunding = self.cleaned_data["crowdfunding"]
+        product = self.cleaned_data["product"]
         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,
-                "periodicity": periodicity,
-                "projectAccount": portal_project_id,
-                "source": settings.DONATE_PORTAL_REDIRECT_SOURCE,
-            }
-        )
+
+        query_dict = {
+            "amount": amount,
+            "periodicity": periodicity,
+            "projectAccount": portal_project_id,
+            "source": settings.DONATE_PORTAL_REDIRECT_SOURCE,
+        }
+
+        if crowdfunding:
+            query_dict.update(crowdfunding=crowdfunding)
+            if product:
+                query_dict.update(product=product)
+
+        query = urllib.parse.urlencode(query_dict)
+
         return f"{settings.DONATE_PORTAL_REDIRECT_URL}?{query}"
diff --git a/donate/migrations/0024_donateprojectpage_crowdfunding.py b/donate/migrations/0024_donateprojectpage_crowdfunding.py
new file mode 100644
index 00000000..cee136b8
--- /dev/null
+++ b/donate/migrations/0024_donateprojectpage_crowdfunding.py
@@ -0,0 +1,98 @@
+# Generated by Django 4.0.4 on 2022-07-26 10:35
+
+import wagtail.blocks
+import wagtail.fields
+import wagtail.images.blocks
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("donate", "0023_donatesecretpreviewpage"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="donateprojectpage",
+            name="crowdfunding",
+            field=wagtail.fields.StreamField(
+                [
+                    (
+                        "reward_block",
+                        wagtail.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.blocks.CharBlock(label="Název odměny"),
+                                ),
+                                (
+                                    "description",
+                                    wagtail.blocks.CharBlock(
+                                        label="Popis", max_length=255, required=False
+                                    ),
+                                ),
+                                ("amount", wagtail.blocks.IntegerBlock(label="Částka")),
+                                (
+                                    "image",
+                                    wagtail.images.blocks.ImageChooserBlock(
+                                        label="Obrázek"
+                                    ),
+                                ),
+                                (
+                                    "delivery_date",
+                                    wagtail.blocks.DateBlock(
+                                        label="Datum dodání", required=False
+                                    ),
+                                ),
+                                (
+                                    "reward_id",
+                                    wagtail.blocks.IntegerBlock(
+                                        help_text="Vyplňte pouze v případě, že odměna nemá varianty",
+                                        label="ID odměny",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "crm_product_description",
+                                    wagtail.blocks.CharBlock(
+                                        help_text='Bude předán systému v parametru "product"',
+                                        label="Popis produktu pro CRM",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "variant_list",
+                                    wagtail.blocks.ListBlock(
+                                        wagtail.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "reward_id",
+                                                    wagtail.blocks.IntegerBlock(
+                                                        label="ID odměny"
+                                                    ),
+                                                ),
+                                                (
+                                                    "title",
+                                                    wagtail.blocks.CharBlock(
+                                                        help_text="Například velikost: S",
+                                                        label="Název varianty",
+                                                        max_length=12,
+                                                    ),
+                                                ),
+                                            ]
+                                        ),
+                                        label="Varianty",
+                                        required=False,
+                                    ),
+                                ),
+                            ]
+                        ),
+                    )
+                ],
+                blank=True,
+                use_json_field=None,
+                verbose_name="Crowdfunding bloky",
+            ),
+        ),
+    ]
diff --git a/donate/models.py b/donate/models.py
index 83574449..a52d701d 100644
--- a/donate/models.py
+++ b/donate/models.py
@@ -27,6 +27,7 @@ from shared.models import (
 from shared.utils import get_subpage_url, make_promote_panels
 from tuning import admin_help
 
+from .blocks import CrowdfundingRewardBlock
 from .forms import DonateForm
 from .utils import get_donated_amount_from_api
 
@@ -461,6 +462,12 @@ class DonateProjectPage(
     # we will use photo as search image
     search_image = None
 
+    crowdfunding = StreamField(
+        [("reward_block", CrowdfundingRewardBlock())],
+        verbose_name="Crowdfunding bloky",
+        blank=True,
+    )
+
     ### PANELS
 
     content_panels = Page.content_panels + [
@@ -503,6 +510,12 @@ class DonateProjectPage(
             ],
             "nastavení darů",
         ),
+        MultiFieldPanel(
+            [
+                FieldPanel("crowdfunding"),
+            ],
+            "Nastavení crowdfundingových odměn",
+        ),
         FieldPanel("coalition_design"),
     ]
 
diff --git a/donate/templates/donate/blocks/crowdfunding_reward_block.html b/donate/templates/donate/blocks/crowdfunding_reward_block.html
new file mode 100644
index 00000000..59c54796
--- /dev/null
+++ b/donate/templates/donate/blocks/crowdfunding_reward_block.html
@@ -0,0 +1,47 @@
+{% load wagtailimages_tags %}
+
+<div class="project-donate-form project-donate-form__right mb-3">
+    <form method="post">
+        {% csrf_token %}
+        <input type="hidden" name="portal_project_id" value="{{ page.portal_project_id }}">
+        <input type="hidden" name="periodicity" value="99999">
+        <input type="hidden" name="amount" value="{{ self.amount }}">
+        <input type="hidden" name="product" value="{{ self.crm_product_description }}">
+        <h3 class="lead mb-3">{{ self.title }}</h3>
+        <div class="row">
+            <figure class="col-12 col-md-7">
+                {% image self.image fill-500x800 as img %}
+                <img src="{{ img.url }}" alt="{{ img.alt }}" class="w-100">
+            </figure>
+            <div class="col-12 col-md-5">
+                {{ self.description }}<br>
+                {% if self.variant_list %}
+                    <small>Zvolte si varaintu:</small>
+                    {% for variant in self.variant_list %}
+                        <div class="custom-control form-control-md custom-radio">
+                            <input type="radio" id="reward-{{ variant.reward_id }}" name="crowdfunding"
+                                   value="{{ variant.reward_id }}"
+                                   class="custom-control-input form-control-md" required>
+                            <label class="custom-control-label col-form-label-lg"
+                                   for="reward-{{ variant.reward_id }}">{{ variant.title }}</label>
+                        </div>
+                    {% endfor %}
+
+                    {% else %}
+                    <input id="reward-{{ self.reward_id }}" name="crowdfunding"
+                                   value="{{ self.reward_id }}" hidden
+                                   class="custom-control-input form-control-md" required>
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mt-2">
+            <div class="col-7 mb-2 mb-md-0">
+                <button type="submit" class="btn btn-danger btn-md">Darovat {{ self.amount }}&nbsp;Kč</button>
+            </div>
+            <p class="col-12 col-md-5">
+                Dodání do: <br>
+                <time datetime="2019-06-18">{{ self.delivery_date|date:"d. m. Y" }}</time>
+            </p>
+        </div>
+    </form>
+</div>
diff --git a/donate/templates/donate/donate_project_page.html b/donate/templates/donate/donate_project_page.html
index 1eb05714..907c6876 100644
--- a/donate/templates/donate/donate_project_page.html
+++ b/donate/templates/donate/donate_project_page.html
@@ -99,7 +99,13 @@
                   <input type="hidden" name="periodicity" value="99999">
                   {% endif %}
                   <div class="form-group row mb-4 align-items-center">
-                      <legend class="col-form-label col-md-12 col-form-label-lg">Částka</legend>
+                      <legend class="col-form-label col-md-12 col-form-label-lg">
+                          {% if self.crowdfunding %}
+                              Částka bez odměny
+                          {% else %}
+                              Částka
+                          {% endif %}
+                      </legend>
                       <div class="col-md-12">
                           {% if page.allow_periodic_donations %}
                           <div id="monthlyAmounts" data-default-selected="{{ page.form_monthly_preselected }}">
@@ -135,6 +141,9 @@
               </div><!-- /project-donate-form__right -->
             </div>
 
+              {% for block in self.crowdfunding %}
+                  {% include_block block %}
+            {% endfor %}
           </div>
         </div><!-- /column -->
 
-- 
GitLab