Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.kesaseteli.example
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,5 @@ ENABLE_ADMIN=1
PASSWORD_LOGIN_DISABLED=0
CREATE_SUMMERVOUCHER_CONFIGURATION_2026=1
CREATE_SUMMERVOUCHER_CONFIGURATION_CURRENT_YEAR=1
ENSURE_EMAIL_TEMPLATES=1
ENSURE_EMAIL_TEMPLATES=1
AD_ADMIN_GROUP_NAME=
1 change: 1 addition & 0 deletions backend/kesaseteli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ env variables / settings are provided by Azure blob storage:
| `NEXT_PUBLIC_DISABLE_VTJ` | A boolean value. If set to True, VTJ client usage is disabled. Default is False. |
| `CREATE_SUMMERVOUCHER_CONFIGURATION_CURRENT_YEAR` | A boolean value. If set to True, creates a new `SummerVoucherConfiguration` for the current year. Default is False. |
| `CREATE_SUMMERVOUCHER_CONFIGURATION_2026` | A boolean value. If set to True, creates a new `SummerVoucherConfiguration` for the year 2026. Default is False. |
| `AD_ADMIN_GROUP_NAME` | The name of the AD group that maps to Django admin permissions. Default is None (feature disabled). |

## Documentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,7 @@ def generate_data_row(
elif field.title == RECEIVED_DATE_FIELD_TITLE:
submitted_at = getattr(summer_voucher, "submitted_at", None)
cell_value = (
submitted_at.astimezone().strftime("%d/%m/%Y")
if submitted_at
else ""
submitted_at.astimezone().strftime("%d/%m/%Y") if submitted_at else ""
)
else:
attr_names = field.model_fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,145 @@


class Migration(migrations.Migration):

dependencies = [
('applications', '0037_set_year_2026_schools'),
("applications", "0037_set_year_2026_schools"),
]

operations = [
migrations.CreateModel(
name='SummerVoucherConfiguration',
name="SummerVoucherConfiguration",
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='time created')),
('modified_at', models.DateTimeField(auto_now=True, verbose_name='time modified')),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('year', models.IntegerField(unique=True, validators=[django.core.validators.MinValueValidator(2020)], verbose_name='year')),
('voucher_value_in_euros', models.PositiveIntegerField(verbose_name='voucher value in euros')),
('min_work_compensation_in_euros', models.PositiveIntegerField(verbose_name='minimum work compensation in euros')),
('min_work_hours', models.PositiveIntegerField(verbose_name='minimum work hours')),
('target_group', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('primary_target_group', '9. luokkalainen'), ('secondary_target_group', 'Toisen asteen ensimmäisen vuoden opiskelija')], max_length=256), size=None, verbose_name='target group')),
(
"created_at",
models.DateTimeField(
auto_now_add=True, verbose_name="time created"
),
),
(
"modified_at",
models.DateTimeField(auto_now=True, verbose_name="time modified"),
),
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"year",
models.IntegerField(
unique=True,
validators=[django.core.validators.MinValueValidator(2020)],
verbose_name="year",
),
),
(
"voucher_value_in_euros",
models.PositiveIntegerField(verbose_name="voucher value in euros"),
),
(
"min_work_compensation_in_euros",
models.PositiveIntegerField(
verbose_name="minimum work compensation in euros"
),
),
(
"min_work_hours",
models.PositiveIntegerField(verbose_name="minimum work hours"),
),
(
"target_group",
django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(
choices=[
("primary_target_group", "9. luokkalainen"),
(
"secondary_target_group",
"Toisen asteen ensimmäisen vuoden opiskelija",
),
],
max_length=256,
),
size=None,
verbose_name="target group",
),
),
],
options={
'verbose_name': 'summer voucher configuration',
'verbose_name_plural': 'summer voucher configurations',
'ordering': ['-year'],
"verbose_name": "summer voucher configuration",
"verbose_name_plural": "summer voucher configurations",
"ordering": ["-year"],
},
),
migrations.AlterField(
model_name='employersummervoucher',
name='target_group',
field=models.CharField(blank=True, choices=[('primary_target_group', '9. luokkalainen'), ('secondary_target_group', 'Toisen asteen ensimmäisen vuoden opiskelija')], help_text="Summer voucher's target group type", max_length=256, verbose_name='summer voucher target group'),
model_name="employersummervoucher",
name="target_group",
field=models.CharField(
blank=True,
choices=[
("primary_target_group", "9. luokkalainen"),
(
"secondary_target_group",
"Toisen asteen ensimmäisen vuoden opiskelija",
),
],
help_text="Summer voucher's target group type",
max_length=256,
verbose_name="summer voucher target group",
),
),
migrations.AlterField(
model_name='historicalemployersummervoucher',
name='target_group',
field=models.CharField(blank=True, choices=[('primary_target_group', '9. luokkalainen'), ('secondary_target_group', 'Toisen asteen ensimmäisen vuoden opiskelija')], help_text="Summer voucher's target group type", max_length=256, verbose_name='summer voucher target group'),
model_name="historicalemployersummervoucher",
name="target_group",
field=models.CharField(
blank=True,
choices=[
("primary_target_group", "9. luokkalainen"),
(
"secondary_target_group",
"Toisen asteen ensimmäisen vuoden opiskelija",
),
],
help_text="Summer voucher's target group type",
max_length=256,
verbose_name="summer voucher target group",
),
),
migrations.AlterField(
model_name='historicalyouthsummervoucher',
name='target_group',
field=models.CharField(blank=True, choices=[('primary_target_group', '9. luokkalainen'), ('secondary_target_group', 'Toisen asteen ensimmäisen vuoden opiskelija')], help_text="Summer voucher's target group type", max_length=256, verbose_name='summer voucher target group'),
model_name="historicalyouthsummervoucher",
name="target_group",
field=models.CharField(
blank=True,
choices=[
("primary_target_group", "9. luokkalainen"),
(
"secondary_target_group",
"Toisen asteen ensimmäisen vuoden opiskelija",
),
],
help_text="Summer voucher's target group type",
max_length=256,
verbose_name="summer voucher target group",
),
),
migrations.AlterField(
model_name='youthsummervoucher',
name='target_group',
field=models.CharField(blank=True, choices=[('primary_target_group', '9. luokkalainen'), ('secondary_target_group', 'Toisen asteen ensimmäisen vuoden opiskelija')], help_text="Summer voucher's target group type", max_length=256, verbose_name='summer voucher target group'),
model_name="youthsummervoucher",
name="target_group",
field=models.CharField(
blank=True,
choices=[
("primary_target_group", "9. luokkalainen"),
(
"secondary_target_group",
"Toisen asteen ensimmäisen vuoden opiskelija",
),
],
help_text="Summer voucher's target group type",
max_length=256,
verbose_name="summer voucher target group",
),
),
]
92 changes: 76 additions & 16 deletions backend/kesaseteli/applications/migrations/0039_emailtemplate.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,94 @@
# Generated by Django 5.1.15 on 2026-01-09 16:22

import applications.validators
import uuid

from django.db import migrations, models

import applications.validators

class Migration(migrations.Migration):

class Migration(migrations.Migration):
dependencies = [
('applications', '0038_summervoucherconfiguration_and_more'),
("applications", "0038_summervoucherconfiguration_and_more"),
]

operations = [
migrations.CreateModel(
name='EmailTemplate',
name="EmailTemplate",
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='time created')),
('modified_at', models.DateTimeField(auto_now=True, verbose_name='time modified')),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('type', models.CharField(choices=[('activation', 'Activation'), ('additional_info_request', 'Additional information request'), ('processing', 'Processing'), ('youth_summer_voucher', 'Youth summer voucher')], max_length=64, verbose_name='template type')),
('language', models.CharField(choices=[('fi', 'suomi'), ('sv', 'svenska'), ('en', 'english')], max_length=2, verbose_name='language')),
('subject', models.CharField(max_length=255, validators=[applications.validators.validate_template_syntax], verbose_name='subject')),
('html_body', models.TextField(validators=[applications.validators.validate_template_syntax], verbose_name='HTML body')),
('text_body', models.TextField(blank=True, help_text='Text body will be auto-generated from HTML body.', validators=[applications.validators.validate_template_syntax], verbose_name='text body')),
(
"created_at",
models.DateTimeField(
auto_now_add=True, verbose_name="time created"
),
),
(
"modified_at",
models.DateTimeField(auto_now=True, verbose_name="time modified"),
),
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"type",
models.CharField(
choices=[
("activation", "Activation"),
(
"additional_info_request",
"Additional information request",
),
("processing", "Processing"),
("youth_summer_voucher", "Youth summer voucher"),
],
max_length=64,
verbose_name="template type",
),
),
(
"language",
models.CharField(
choices=[("fi", "suomi"), ("sv", "svenska"), ("en", "english")],
max_length=2,
verbose_name="language",
),
),
(
"subject",
models.CharField(
max_length=255,
validators=[applications.validators.validate_template_syntax],
verbose_name="subject",
),
),
(
"html_body",
models.TextField(
validators=[applications.validators.validate_template_syntax],
verbose_name="HTML body",
),
),
(
"text_body",
models.TextField(
blank=True,
help_text="Text body will be auto-generated from HTML body.",
validators=[applications.validators.validate_template_syntax],
verbose_name="text body",
),
),
],
options={
'verbose_name': 'email template',
'verbose_name_plural': 'email templates',
'ordering': ['type', 'language'],
'unique_together': {('type', 'language')},
"verbose_name": "email template",
"verbose_name_plural": "email templates",
"ordering": ["type", "language"],
"unique_together": {("type", "language")},
},
),
]
Loading
Loading