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 }} 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