Skip to content

Commit

Permalink
[144] Make contributions dynamic
Browse files Browse the repository at this point in the history
Also fixed the validation which checks that the higher amount is higher
than the highest tier. And fixed the clearing/setting of the higher
amount radio button, which was working on the signup page but not on the
contribution page, so I just copied it from the signup page and it
worked.
  • Loading branch information
Gwildor committed Mar 27, 2024
1 parent f5c05bb commit 909ed85
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 40 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ DIRECTADMIN_PASSWORD=pass

# Socialisten and ROOD specific variables
ORGANIZATION_NAME='ROOD, Socialistische Jongeren'
ORGANIZATION_ID='rood'
ORGANIZATION_EMAIL='[email protected]'
NOREPLY_ADDRESS='[email protected]'
HOMEPAGE='roodjongeren.nl'
Expand Down
6 changes: 6 additions & 0 deletions config/instances/ds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
contribution:
tiers:
- amount: 900
description: Studenten en werklozen
- amount: null
description: "Werkenden: 0,5% van het netto inkomen (minimaal €15 per kwartaal)"
10 changes: 10 additions & 0 deletions config/instances/rood.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
contribution:
tiers:
- amount: 750
description: Tot en met €2000 bruto
- amount: 1500
description: €2000-€3499 bruto
- amount: 2250
description: €3500 bruto en daarboven
- amount: null
description: ik betaal een hogere contributie, namelijk:
1 change: 1 addition & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ parameters:
documents_directory: '%kernel.project_dir%/var/documents'
mollie_payment_description: 'Contributiebetaling %env(ORGANIZATION_NAME)%'
app.organizationName: '%env(ORGANIZATION_NAME)%'
app.organizationID: '%env(ORGANIZATION_ID)%'
app.noReplyAddress: '%env(NOREPLY_ADDRESS)%'
app.homepageUrl: '%env(HOMEPAGE)%'
app.orgLogo: '%env(ORG_LOGO)%'
Expand Down
12 changes: 9 additions & 3 deletions src/Controller/ContributionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use DateTime;
use DateInterval;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Yaml\Yaml;

class ContributionController extends AbstractController
{
Expand Down Expand Up @@ -154,8 +155,12 @@ public function webhook(Request $request, MollieApiClient $mollieApiClient): Res
* @Route("/automatische-incasso", name="member_contribution_automatic_collection")
*/
public function automaticCollection(Request $request, LoggerInterface $logger): Response {
$form = $this->createForm(ContributionIncomeType::class);
$form->setData(750);
$projectRoot = $this->getParameter('kernel.project_dir');
$org_config = Yaml::parseFile($projectRoot . '/config/instances/' . $this->getParameter('app.organizationID') . '.yaml');

$form = $this->createForm(ContributionIncomeType::class, null, [
'contribution' => $org_config['contribution']
]);

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
Expand All @@ -170,7 +175,8 @@ public function automaticCollection(Request $request, LoggerInterface $logger):

return $this->render('user/contribution/automatic-collection.html.twig', [
'success' => false,
'form' => $form->createView()
'form' => $form->createView(),
'contribution' => $org_config['contribution']
]);
}

Expand Down
7 changes: 6 additions & 1 deletion src/Controller/MemberController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Form\FormError;
use Symfony\Component\Yaml\Yaml;

use DateTime;
use DateInterval;
Expand Down Expand Up @@ -86,13 +87,17 @@ public function home(Request $request): Response {
* @Route("/aanmelden", name="member_apply")
*/
public function apply(Request $request): Response {
$projectRoot = $this->getParameter('kernel.project_dir');
$org_config = Yaml::parseFile($projectRoot . '/config/instances/' . $this->getParameter('app.organizationID') . '.yaml');

$membershipApplication = new MembershipApplication();
$membershipApplication->setRegistrationTime(new \DateTime());
$membershipApplication->setContributionPeriod(Member::PERIOD_QUARTERLY);
$form = $this->createForm(MembershipApplicationType::class, $membershipApplication, [
'use_middle_name' => $this->getParameter('app.useMiddleName'),
'privacy_policy_url' => $this->getParameter('app.privacyPolicyUrl'),
'organization_name' => $this->getParameter('app.organizationName')
'organization_name' => $this->getParameter('app.organizationName'),
'contribution' => $org_config['contribution']
]);

$form->handleRequest($request);
Expand Down
39 changes: 28 additions & 11 deletions src/Form/Contribution/ContributionIncomeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,32 @@
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Form\Extension\Core\Type\{ ChoiceType, MoneyType };
use Symfony\Component\OptionsResolver\OptionsResolver;

class ContributionIncomeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$choices = [];
$max_amount = 0;
foreach ($options['contribution']['tiers'] as $tier) {
if ($tier['amount'] === null) {
$choices[$tier['description']] = 0;
} else {
$description = $tier['description'] . ' (ik betaal €' . number_format($tier['amount'] / 100, 2, ',') . ' contributie per kwartaal)';
$choices[$description] = $tier['amount'];
}

if ($tier['amount'] > $max_amount) {
$max_amount = $tier['amount'];
}
}

$builder
->add('contributionAmount', ChoiceType::class, [
'error_bubbling' => true,
'label' => 'Maandinkomen',
'choices' => [
'Tot en met €2000 (ik betaal €7,50 contributie per kwartaal)' => 750,
'€2000-€3499 (ik betaal €15,00 contributie per kwartaal)' => 1500,
'€3500 en daarboven (ik betaal €22,50 contributie per kwartaal)' => 2250,
'ik betaal een hogere contributie, namelijk:' => 0,
],
'choices' => $choices,
'expanded' => true
])
->add('otherAmount', MoneyType::class, [
Expand All @@ -31,21 +42,27 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'divisor' => 100,
'required' => false,
'attr' => [
'min' => 2250
'min' => $max_amount / 100
],
'constraints' => new Assert\GreaterThan([
'value' => 22.50,
'message' => 'Als je een hoger bedrag selecteert, moet dit hoger dan {{ compared_value }} zijn'
'value' => $max_amount,
'message' => 'Als je een hoger bedrag selecteert, moet dit hoger dan ' . number_format($max_amount / 100, 2, ',') . ' zijn.'
])
]);

$builder->addModelTransformer(new CallbackTransformer(
fn($model) => [
'contributionAmount' => $model > 2250 ? null : $model,
'otherAmount' => $model > 2250 ? $model : null
'contributionAmount' => $model > $max_amount ? null : $model,
'otherAmount' => $model > $max_amount ? $model : null
],
fn($norm) => $norm['contributionAmount'] === 0 ? $norm['otherAmount'] : $norm['contributionAmount']
));
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired([
'contribution'
]);
}
}
7 changes: 6 additions & 1 deletion src/Form/MembershipApplicationType.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
])
->add('contributionPerPeriodInCents', ContributionIncomeType::class, [
'label' => 'Contributiebedrag',
'error_bubbling' => true
'error_bubbling' => true,
'contribution' => $options['contribution']
])
->add('accept', CheckboxType::class, [
'label' => 'Ik heb het <a target="_blank" href="' . $options['privacy_policy_url'] . '">privacybeleid</a> gelezen en ik ga daarmee akkoord.',
Expand Down Expand Up @@ -78,5 +79,9 @@ public function configureOptions(OptionsResolver $resolver)
$resolver->setRequired([
'organization_name'
]);

$resolver->setRequired([
'contribution'
]);
}
}
54 changes: 33 additions & 21 deletions templates/user/contribution/automatic-collection.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,28 @@
{% block scripts %}
{{ parent() }}
<script>
const otherAmountInput = document.getElementById("contribution_income_otherAmount");
const otherAmountRadio = document.getElementById("form_contributionAmount_{{ form.contributionAmount.vars.choices | length }}");
otherAmountInput.disabled = !otherAmountRadio.checked;
for (var i = 1; i <= {{ form.contributionAmount.vars.choices | length }}; i++) {
document.getElementById("form_contributionAmount_" + i).addEventListener("input", (event) => {
otherAmountInput.disabled = !otherAmountRadio.checked;
});
function updateContribution() {
let other = document.querySelector('.other-amount');
if (document.querySelector('.choice :checked').value !== 0) {
other.value = '';
}
}
function updateOtherAmount() {
let other = document.querySelector('.other-amount');
if (other.value != '')
{
document.querySelector('.choice [value="0"]').checked = true;
}
}
document.addEventListener('change', e => {
if (e.target.closest) {
if (e.target.closest('.other-amount')) {
updateOtherAmount();
} else if (e.target.closest('.choices')) {
updateContribution();
}
}
})
</script>
{% endblock %}

Expand All @@ -30,8 +43,10 @@
{% else %}
<p>
Contributie zal elk kwartaal automatisch van je rekening afgeschreven worden via automatisch incasso.
Hoeveel je hierbij betaalt hangt af van je inkomen:
Hoeveel je hierbij betaalt hangt af van je inkomen.
</p>

{% if contribution.tiers|length > 2 %}
<table class="table">
<thead>
<tr>
Expand All @@ -40,20 +55,17 @@
</tr>
</thead>
<tbody>
<tr>
<td>Tot en met €2000</td>
<td>€7,50 per kwartaal (€2,50 per maand)</td>
</tr>
<tr>
<td>€2000-€3499</td>
<td>€15,00 per kwartaal (€5 per maand)</td>
</tr>
<tr>
<td>€3500 en daarboven</td>
<td>€22,50 per kwartaal (€7,50 per maand)</td>
</tr>
{% for tier in contribution.tiers %}
{% if tier.amount is not same as(null) %}
<tr>
<td>{{ tier.description }}</td>
<td>€{{ (tier.amount / 100)|number_format(2, ',') }} per kwartaal (€{{ (tier.amount / 100 / 3)|number_format(2, ',') }} per maand)</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endif %}

{% if form.vars.submitted and not form.vars.valid %}
<div class="error">
Expand Down
6 changes: 3 additions & 3 deletions templates/user/member/apply.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
{% block body %}
<div id="center-form-wrapper" class="big-form">

<img id="logo" src="{{ asset('assets/image/logo.png') }}" />
<img id="logo" src="{{ asset(orgLogo) }}" />

<span class="center-form-title">
Inschrijven bij <span class="rood">ROOD</span>
Inschrijven bij <span class="rood">{{ orgnaamkort }}</span>
</span>

{% if form.vars.submitted and not form.vars.valid %}
Expand Down Expand Up @@ -67,7 +67,7 @@
{{ form_row(form.preferredDivision, { attr: { class: 'text-input' } }) }}

<p>
Selecteer wat er voor jou van toepassing is:
Bij {{ orgnaamkort }} hebben we contributie op basis van je bruto maandinkomen. Selecteer wat er voor jou van toepassing is:
</p>
<div class="choices">
{% for option in form.contributionPerPeriodInCents.contributionAmount %}
Expand Down

0 comments on commit 909ed85

Please sign in to comment.