Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obtain submission price from variable #4770

Open
wants to merge 7 commits into
base: stable/2.8.x
Choose a base branch
from
35 changes: 31 additions & 4 deletions docs/manual/forms/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,37 @@ product bevat een prijs die gebruikt kan worden als betaald moet worden voor
het product. Betaling kan ingesteld worden door de juiste **Betaalprovider** te
selecteren.

Ten slotte kunt u ervoor kiezen om de prijs van het gekoppeld product te
gebruiken of logica regels op te stellen voor het bepalen van de prijs. Dit
laatste kunt u instellen onder **Prijslogica**. De **Prijslogica** volgt verder
dezelfde regels als reguliere **Logica**.
Er zijn drie manieren om de prijs van een inzending te bepalen:

**Gebruik de prijs van het gekoppeld product**

Dit is de meest eenvoudige variant. Er geldt een vaste prijs, die ingesteld wordt op
het product.

**Gebruik een variabele**

Dit is de meest flexibele variant - met behulp van normale **Logica** kan je de waarde
van een variabele zetten om de prijs te berekenen. In het formulier wijs je naar deze
variabele en de waarde van de variabele wordt als prijs gebruikt. Je kan enkel
variabelen selecteren die een numeriek gegevenstype hebben (integer, float).

Let op - er moet altijd een prijs ingesteld staan op het product om de betalingsmodule
te activeren.

.. warning:: Deze methode is foutgevoelig - indien de waarde van de variabele niet
geschikt is om als prijs te gebruiken of er komt geen geldig getal uit, dan zal
de eindgebruiker fouten in het formulier ervaren. Zorg ervoor dat de formulieren
goed getest zijn!

.. versionadded:: 2.8.1 Uitzonderlijk is deze functionaliteit in een patch-release
toegevoegd. Versie 2.8.0 en ouder hebben deze functionaliteit niet.

**Gebruik prijslogica**

Voor eenvoudige condities kan je prijslogic instellen. Onder een bepaalde conditie geldt
een bepaalde, vaste, prijs. Indien aan geen enkele conditie voldaan is, dan wordt de
prijs van het gekoppeld product gebruikt. De **Prijslogica** volgt verder dezelfde
regels als reguliere **Logica**.

Zie ook: :ref:`configuration_payment_index`

Expand Down
25 changes: 20 additions & 5 deletions src/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: Open Forms API
version: 2.8.0
version: 2.8.1
description: |2

Open Forms provides an API to manage multi-page or multi-step forms.
Expand Down Expand Up @@ -1330,6 +1330,7 @@ paths:
- `authenticationBackendOptions`
- `paymentBackend`
- `paymentBackendOptions`
- `priceVariableKey`
- `product`
- `category`
- `theme`
Expand Down Expand Up @@ -1403,6 +1404,7 @@ paths:
- `authenticationBackendOptions`
- `paymentBackend`
- `paymentBackendOptions`
- `priceVariableKey`
- `product`
- `category`
- `theme`
Expand Down Expand Up @@ -1920,6 +1922,7 @@ paths:
- `authenticationBackendOptions`
- `paymentBackend`
- `paymentBackendOptions`
- `priceVariableKey`
- `product`
- `category`
- `theme`
Expand Down Expand Up @@ -1999,6 +2002,7 @@ paths:
- `authenticationBackendOptions`
- `paymentBackend`
- `paymentBackendOptions`
- `priceVariableKey`
- `product`
- `category`
- `theme`
Expand Down Expand Up @@ -2082,6 +2086,7 @@ paths:
- `authenticationBackendOptions`
- `paymentBackend`
- `paymentBackendOptions`
- `priceVariableKey`
- `product`
- `category`
- `theme`
Expand Down Expand Up @@ -7576,7 +7581,7 @@ components:

Note that this schema is used for both non-admin users filling out forms and
admin users designing forms. The fields that are only relevant for admin users are:
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `priceVariableKey`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
properties:
uuid:
type: string
Expand Down Expand Up @@ -7639,6 +7644,11 @@ components:
items:
$ref: '#/components/schemas/PaymentOption'
readOnly: true
priceVariableKey:
type: string
description: Key of the variable that contains the calculated submission
price.
pattern: ^(\w|\w[\w.\-]*\w)$
appointmentOptions:
allOf:
- $ref: '#/components/schemas/AppointmentOptions'
Expand Down Expand Up @@ -8077,7 +8087,7 @@ components:

Note that this schema is used for both non-admin users filling out forms and
admin users designing forms. The fields that are only relevant for admin users are:
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `priceVariableKey`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
properties:
name:
type: string
Expand Down Expand Up @@ -8248,7 +8258,7 @@ components:

Note that this schema is used for both non-admin users filling out forms and
admin users designing forms. The fields that are only relevant for admin users are:
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `priceVariableKey`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
properties:
name:
type: string
Expand Down Expand Up @@ -9236,7 +9246,7 @@ components:

Note that this schema is used for both non-admin users filling out forms and
admin users designing forms. The fields that are only relevant for admin users are:
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
`internalName`, `registrationBackends`, `registrationBackend`, `registrationBackendOptions`, `authenticationBackendOptions`, `paymentBackend`, `paymentBackendOptions`, `priceVariableKey`, `product`, `category`, `theme`, `activateOn`, `deactivateOn`, `isDeleted`, `submissionConfirmationTemplate`, `askPrivacyConsent`, `askStatementOfTruth`, `submissionsRemovalOptions`, `confirmationEmailTemplate`, `sendConfirmationEmail`, `displayMainWebsiteLink`, `includeConfirmationPageContentInPdf`, `translations`, `brpPersonenRequestOptions`.
properties:
uuid:
type: string
Expand Down Expand Up @@ -9299,6 +9309,11 @@ components:
items:
$ref: '#/components/schemas/PaymentOption'
readOnly: true
priceVariableKey:
type: string
description: Key of the variable that contains the calculated submission
price.
pattern: ^(\w|\w[\w.\-]*\w)$
appointmentOptions:
allOf:
- $ref: '#/components/schemas/AppointmentOptions'
Expand Down
2 changes: 1 addition & 1 deletion src/openforms/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@
and it plays nice with other available components.
"""

API_VERSION = "2.8.0"
API_VERSION = "2.8.1"

SPECTACULAR_SETTINGS = {
"SCHEMA_PATH_PREFIX": "/api/v2",
Expand Down
1 change: 1 addition & 0 deletions src/openforms/forms/api/serializers/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ class Meta:
"payment_backend",
"payment_backend_options",
"payment_options",
"price_variable_key",
"appointment_options",
"literals",
"product",
Expand Down
31 changes: 31 additions & 0 deletions src/openforms/forms/migrations/0101_form_price_variable_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 4.2.16 on 2024-10-18 10:28

import re

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("forms", "0100_merge_20240920_1816"),
]

operations = [
migrations.AddField(
model_name="form",
name="price_variable_key",
field=models.TextField(
blank=True,
help_text="Key of the variable that contains the calculated submission price.",
validators=[
django.core.validators.RegexValidator(
message="Invalid variable key. It must only contain alphanumeric characters, underscores, dots and dashes and should not be ended by dash or dot.",
regex=re.compile("^(\\w|\\w[\\w.\\-]*\\w)$"),
)
],
verbose_name="price variable key",
),
),
]
11 changes: 11 additions & 0 deletions src/openforms/forms/models/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from openforms.config.models import GlobalConfiguration
from openforms.data_removal.constants import RemovalMethods
from openforms.formio.typing import Component
from openforms.formio.validators import variable_key_validator
from openforms.payments.fields import PaymentBackendChoiceField
from openforms.payments.registry import register as payment_register
from openforms.plugins.constants import UNIQUE_ID_MAX_LENGTH
Expand Down Expand Up @@ -90,6 +91,16 @@ class Form(models.Model):
payment_backend_options = models.JSONField(
_("payment backend options"), default=dict, blank=True, null=True
)
# XXX a Foreign Key to FormVariable would be nicer, but we can't do this yet since
# the frontend saves the variables *after* the form record itself is saved.
price_variable_key = models.TextField(
_("price variable key"),
blank=True,
help_text=_(
"Key of the variable that contains the calculated submission price."
),
validators=[variable_key_validator],
)

# authentication
authentication_backends = AuthenticationBackendMultiSelectField(
Expand Down
36 changes: 36 additions & 0 deletions src/openforms/js/compiled-lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,12 @@
"value": "The text that will be displayed in the form step to save the current information. Leave blank to get value from global configuration."
}
],
"8M403q": [
{
"type": 0,
"value": "Soft required fields should be filled out, but empty values don't block the users' progress. Sometimes this is needed for legal reasons. A component cannot be hard and soft required at the same time."
}
],
"8NbOpb": [
{
"type": 0,
Expand Down Expand Up @@ -1455,6 +1461,12 @@
"value": "Select the allowed authentication plugins to log in at the start of the form."
}
],
"Ckzpff": [
{
"type": 0,
"value": "Use a variable for the price"
}
],
"CtjZFq": [
{
"type": 0,
Expand Down Expand Up @@ -2703,6 +2715,12 @@
"value": "Select existing form definition"
}
],
"QL4SGQ": [
{
"type": 0,
"value": "Soft required"
}
],
"QLTh2N": [
{
"type": 0,
Expand Down Expand Up @@ -4783,6 +4801,12 @@
"value": "Session will expire"
}
],
"jtWzSW": [
{
"type": 0,
"value": "option 2: € 15,99"
}
],
"k1+ljn": [
{
"type": 0,
Expand Down Expand Up @@ -5497,6 +5521,12 @@
"value": "Regular expression for city"
}
],
"sxdJ/8": [
{
"type": 0,
"value": "option 1: € 10,99"
}
],
"t5fg/K": [
{
"type": 0,
Expand Down Expand Up @@ -5835,6 +5865,12 @@
"value": "Cancel"
}
],
"x6oxfg": [
{
"type": 0,
"value": "Variable"
}
],
"xI6md8": [
{
"type": 0,
Expand Down
36 changes: 36 additions & 0 deletions src/openforms/js/compiled-lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,12 @@
"value": "De tekst op de knop om de gegevens van de huidige stap op te slaan en het formulier te onderbreken. Laat dit veld leeg om de standaardinstelling te gebruiken."
}
],
"8M403q": [
{
"type": 0,
"value": "Aangeraden velden moeten in principe ingevuld worden, maar ontbrekende waarden blokkeren de voortgang niet. Dit is soms nodig voor juridische redenen. Een component kan niet tegelijk verplicht en aangeraden zijn."
}
],
"8NbOpb": [
{
"type": 0,
Expand Down Expand Up @@ -1459,6 +1465,12 @@
"value": "Selecteer de toegestane authenticatie-plugins om in te loggen aan het begin van het formulier."
}
],
"Ckzpff": [
{
"type": 0,
"value": "Gebruik een variabele"
}
],
"CtjZFq": [
{
"type": 0,
Expand Down Expand Up @@ -2720,6 +2732,12 @@
"value": "Selecteer een bestaande formulierdefinitie"
}
],
"QL4SGQ": [
{
"type": 0,
"value": "Aangeraden (niet-blokkerend verplicht)"
}
],
"QLTh2N": [
{
"type": 0,
Expand Down Expand Up @@ -4805,6 +4823,12 @@
"value": "Sessie gaat vervallen"
}
],
"jtWzSW": [
{
"type": 0,
"value": "optie 2: € 15,99"
}
],
"k1+ljn": [
{
"type": 0,
Expand Down Expand Up @@ -5519,6 +5543,12 @@
"value": "Reguliere expressie"
}
],
"sxdJ/8": [
{
"type": 0,
"value": "optie 1: € 10,99"
}
],
"t5fg/K": [
{
"type": 0,
Expand Down Expand Up @@ -5857,6 +5887,12 @@
"value": "Annuleren"
}
],
"x6oxfg": [
{
"type": 0,
"value": "Variabele"
}
],
"xI6md8": [
{
"type": 0,
Expand Down
Loading
Loading